There are two ways to display characters: by using glyph information obtained from the font resources, or by using the character rendering classes provided by the Font library.
4.1. Displaying Characters Based on Glyph Information
The GetGlyph()
function of the Font
class returns glyph information in a Glyph
structure. This structure contains the information required to display glyphs as characters and is defined as follows.
struct Glyph { const void* pTexture; struct CharWidths { s8 left; u8 glyphWidth; s8 charWidth; } widths; u8 height; u16 texWidth; u16 texHeight; u16 cellX; u16 cellY; u8 isSheetUpdated; TexFmt texFormat; const TextureObject* pTextureObject; };
The values stored in the various members are as follows. The values of the widths and heights are stored in pixel units.
Member | Description |
---|---|
pTexture
|
Pointer to the sheet (the texture image). |
widths.left
|
Left space width. |
widths.glyphWidth
|
Glyph width. |
widths.charWidth
|
Character width. The right space width can be found by this formula: [character width – glyph width – left space width]. |
height
|
Cell (glyph image) height. |
texWidth
|
Sheet width. |
texHeight
|
Sheet height. |
cellX
|
X-coordinate of the upper-left corner of the cell, taking the upper-left corner of the sheet as the origin. |
cellY
|
Y-coordinate of the upper-left corner of the cell, taking the upper-left corner of the sheet as the origin. |
isSheetUpdated
|
Sheet update flag. Referenced by the Font library. |
texFormat
|
Sheet (texture) format. |
pTextureObject
|
Texture object information and other information. Referenced by the Font library. |
The sheet format definitions correspond as follows to the argument values specified to the glTexImage2D()
function.
Format | format | type |
---|---|---|
FONT_SHEET_FORMAT_A4
|
GL_ALPHA_NATIVE_DMP
|
GL_UNSIGNED_4BITS_DMP
|
FONT_SHEET_FORMAT_A8
|
GL_ALPHA_NATIVE_DMP
|
GL_UNSIGNED_BYTE
|
FONT_SHEET_FORMAT_LA4
|
GL_LUMINANCE_ALPHA_NATIVE_DMP
|
GL_UNSIGNED_BYTE_4_4_DMP
|
FONT_SHEET_FORMAT_LA8
|
GL_LUMINANCE_ALPHA_NATIVE_DMP
|
GL_UNSIGNED_BYTE
|
FONT_SHEET_FORMAT_RGBA4
|
GL_RGBA_NATIVE_DMP
|
GL_UNSIGNED_SHORT_4_4_4_4
|
FONT_SHEET_FORMAT_RGB5A1
|
GL_RGBA_NATIVE_DMP
|
GL_UNSIGNED_SHORT_5_5_5_1
|
FONT_SHEET_FORMAT_RGBA8
|
GL_RGBA_NATIVE_DMP
|
GL_UNSIGNED_BYTE
|
FONT_SHEET_FORMAT_RGB565
|
GL_RGB_NATIVE_DMP
|
GL_UNSIGNED_SHORT_5_6_5
|
FONT_SHEET_FORMAT_RGB8
|
GL_RGB_NATIVE_DMP
|
GL_UNSIGNED_BYTE
|
The following structure members are required in order to identify the location in the sheet of the glyph image to display.
You must note that while the 3DS texture coordinates have their origin at the lower left, the origin of the cell (glyph image) coordinates is at the upper left. Because of this, the calculation of texture coordinates is implemented as in the following sample code.
Glyph glyph; myFont.GetGlyph(&glyph, character); const f32 texLeft = 1.0f * glyph.cellX / glyph.texWidth; const f32 texRight = 1.0f * (glyph.cellX + glyph.widths.glyphWidth) / glyph.texWidth; // Be careful about the differences between glyph image coordinates and texture coordinate origins. const f32 texTop = 1.0f * (glyph.texHeight - glyph.cellY) / glyph.texHeight; const f32 texBottom = 1.0f * (glyph.texHeight - (glyph.cellY + glyph.height)) / glyph.texHeight;
4.2. Using the Font Library Classes
The Font library provides classes for rendering characters and strings. In addition to simply rendering single characters, it also has the following features:
- Changing the text color
- Vertical or horizontal color gradation on the per-character level
- Scaling characters
- Forced fixed-width (monospaced) font display
- Character spacing, line spacing, and tab spacing
- Left-justification or right-justification
- Automatic line wrapping (newlines) in text
- Rendering using format strings (
printf
equivalent) - Processing of tagged strings (customizable)
Several classes are used to render characters with the Font library, and they cooperate as illustrated below. In this process flow, the classes denoted by orange rectangles in the figure below are classes that configure settings for rendering text, and they are instantiated by the application. Also, blue denotes base classes, while green denotes implicitly used classes.
If you use Font library classes to render text, we recommend using the RectDrawer class, which directly generates 3D commands (PICA register settings).
Class | Processing Performed |
---|---|
CharWriter | Renders individual characters. If you do not use TextWriter , inherit this class and form the characters into strings, along with the other processing involved with rendering strings. |
TextWriter | Renders strings. This class provides the basic features for generating strings. |
TagProcessor | Processes tag characters (control characters in the range 0x0000 to 0x001F ). If you want the tag processor to support characters other than the newline character (0x000A ) and the tab character (0x0009 ), define a custom class that inherits TagProcessor . |
RectDrawer | Generates 3D commands from the string display information accumulated in a buffer by the TextWriter (or CharWriter ) class. Generates 3D commands compatible with dedicated shader programs. |
4.2.1. Steps for Implementing in an Application
This section describes the procedures for using the Font library classes to display strings on the screen, using as an example the source code for the ResFont
demo included in the sample demos.
4.2.1.1. Loading and Constructing Font Resources
First, load and construct the font resources used to render text. In the sample demo, a pointer to an instance of the ResFont
class and the font resource filename (that has an extension of bcfnt
) are passed to the InitFont()
function.
//--------------------------------------------------------------------------- //! @brief Constructs ResFont. //! //! @param[out] pFont: Pointer to the font to construct. //! @param[in] filePath: Filename of the font resource to load. //! //! @return Returns whether ResFont was successfully constructed. //--------------------------------------------------------------------------- bool InitFont( nn::font::ResFont* pFont, const char* filePath) { // Load font resources. nn::fs::FileReader fontReader(filePath); s32 fileSize = (s32)fontReader.GetSize(); if ( fileSize <= 0 ) { return false; } void* buffer = s_AppHeap.Allocate(fileSize, nn::font::GlyphDataAlignment); if (buffer == NULL) { return false; } s32 readSize = fontReader.Read(buffer, fileSize); if (readSize != fileSize) { s_AppHeap.Free(buffer); return false; } // Set font resources. bool bSuccess = pFont->SetResource(buffer); NN_ASSERT(bSuccess); //---Fails when resources are already set or already loaded, // or when the resources are invalid. if (! bSuccess) { s_AppHeap.Free(buffer); } // Set the render buffer. const u32 drawBufferSize = nn::font::ResFont::GetDrawBufferSize(buffer); void* drawBuffer = s_AppHeap.Allocate(drawBufferSize, 4); NN_NULL_ASSERT(drawBuffer); pFont->SetDrawBuffer(drawBuffer); return bSuccess; }
In the Font library, textures are loaded with settings such that the GPU directly accesses the sheets that contain the drawn glyph images of the loaded font resources. Accordingly, font resources must be loaded into a buffer in device memory that has 128-byte alignment. Note that the only restriction on the render buffer is the requirement of 4-byte alignment, so this buffer does not need to be allocated in device memory.
For more information about the restrictions that apply when using font resources other than the ResFont class, see 3.3. The ArchiveFont Class and 3.4. The PackedFont Class.
4.2.1.2. Initializing Shaders
Load the shader binary that will be used for text display, and allocate a buffer for the RectDrawer
class. In the sample demo, a pointer to an instance of the RectDrawer
class is passed to the InitShaders()
function.
//--------------------------------------------------------------------------- //! @brief Initializes the shaders. //! //! @param[in,out] pDrawer Pointer to the instance to initialize. //--------------------------------------------------------------------------- void* InitShaders(nn::font::RectDrawer* pDrawer) { nn::fs::FileReader shaderReader(s_ShaderBinaryFilePath); const u32 fileSize = (u32)shaderReader.GetSize(); void* shaderBinary = s_AppHeap.Allocate(fileSize); NN_NULL_ASSERT(shaderBinary); #ifndef NN_BUILD_RELEASE s32 read = #endif // NN_BUILD_RELEASE shaderReader.Read(shaderBinary, fileSize); NN_ASSERT(read == fileSize); const u32 vtxBufCmdBufSize = nn::font::RectDrawer::GetVertexBufferCommandBufferSize( shaderBinary, fileSize); void *const vtxBufCmdBuf = s_AppHeap.Allocate(vtxBufCmdBufSize); NN_NULL_ASSERT(vtxBufCmdBuf); pDrawer->Initialize(vtxBufCmdBuf, shaderBinary, fileSize); s_AppHeap.Free(shaderBinary); return vtxBufCmdBuf; }
In the RectDrawer
class, two buffers are used: the vertex buffer and the command buffer. The vertex buffer contains vertex coordinates for use in rendering. The command buffer stores render commands, but also contains shader binary loading commands (programs, swizzle patterns, constant registers) and other such commands. These buffers are accessed directly by the GPU, so they must be allocated in device memory. There is no required buffer alignment, but we recommend 4-byte or 16-byte alignment.
In the sample demo, the two buffers are allocated in a single region, but functions for getting the required size of each buffer and an initialization function for allocating the buffers separately are also provided. After initialization is successful, you can release the buffer that contains the shader binary.
The SDK contains nnfont_RectDrawerShader.shbin
as the shader binary used in the RectDrawer
class. This shader assumes that an orthogonal projection matrix has been set in which the sizes of the projected screen in screen space and the LCD screen are identical, with the origin of the projection matrix at the upper left of the screen in screen space (although the directions of the y-axis and z-axis are the reverse of the 3DS axes), and also assumes that the modelview matrix is set to a unit matrix. The adjustment of the character display position and size is managed by accumulating transformation matrices in the floating-point constant registers.
4.2.1.3. Allocating a Display String Buffer
Allocate a buffer that accumulates string display information (the display string buffer). The required size of the display string buffer is calculated based on the maximum number of characters to display. When string rendering is complete, the same buffer can be used to accumulate string display information. If the font and characters to display do not change, the stored string display information can be reused unchanged. If the string has previously been rendered in a single color, you can change just the font color and do not need to accumulate the string display information again.
//--------------------------------------------------------------------------- //! @brief Allocates a display string buffer. //! //! @param[in] charMax: Maximum number of characters in the string to display. //! //! @return Returns a pointer to the allocated display string buffer. //--------------------------------------------------------------------------- nn::font::DispStringBuffer* AllocDispStringBuffer(int charMax) { const u32 DrawBufferSize = nn::font::CharWriter::GetDispStringBufferSize(charMax); void *const bufMem = s_AppHeap.Allocate(DrawBufferSize); NN_NULL_ASSERT(bufMem); return nn::font::CharWriter::InitDispStringBuffer(bufMem, charMax); }
There is no need to allocate the display string buffer in device memory. There is no required buffer alignment, but we recommend 4-byte alignment.
4.2.1.4. Rendering Settings
The Font library configures the minimum level of settings required for rendering characters, so the application must appropriately set the following render pipeline stages before rendering.
- Culling
- Scissor test
- Polygon offset
- Early depth test
- Depth test
- Stencil test
- Masking
- Framebuffer object
If the application makes culling or depth test settings to display 3D models or the like, the settings in effect immediately before the text is rendered are applied to the text. However, you can change these settings before rendering.
In the following sample demo, the InitDraw()
function generates commands that configure the rendering settings.
//--------------------------------------------------------------------------- //! @brief Performs the initial settings for rendering. //! //! @param[in] width Screen width. //! @param[in] height Screen height. //--------------------------------------------------------------------------- void InitDraw( int width, int height ) { // Color buffer information. // Align with the orientation of the LCD, and swap the width with the height. const nn::font::ColorBufferInfo colBufInfo = { width, height, PICA_DATA_DEPTH24_STENCIL8_EXT }; const u32 screenSettingCommands[] = { // Viewport settings. NN_FONT_CMD_SET_VIEWPORT( 0, 0, colBufInfo.width, colBufInfo.height ), // Disable scissoring. NN_FONT_CMD_SET_DISABLE_SCISSOR( colBufInfo ), // Disable the w buffer. // Depth range settings. // Disable polygon offset. NN_FONT_CMD_SET_WBUFFER_DEPTHRANGE_POLYGONOFFSET( 0.0f, // wScale : 0.0 disables the W buffer. 0.0f, // Depth range near. 1.0f, // Depth range far. 0, // Polygon offset units : 0.0 disables the polygon offset. colBufInfo), }; nngxAdd3DCommand(screenSettingCommands, sizeof(screenSettingCommands), true); static const u32 s_InitCommands[] = { // Disable culling. NN_FONT_CMD_SET_CULL_FACE( NN_FONT_CMD_CULL_FACE_DISABLE ), // Disable stencil test. NN_FONT_CMD_SET_DISABLE_STENCIL_TEST(), // Disable depth test. // Enable writing of all color buffer components. NN_FONT_CMD_SET_DEPTH_FUNC_COLOR_MASK( false, // isDepthTestEnabled 0, // depthFunc true, // depthMask true, // red true, // green true, // blue true), // alpha // Disable early depth test. NN_FONT_CMD_SET_ENABLE_EARLY_DEPTH_TEST( false ), // Control access to the framebuffer. NN_FONT_CMD_SET_FBACCESS( true, // colorRead true, // colorWrite false, // depthRead false, // depthWrite false, // stencilRead false), // stencilWrite }; nngxAdd3DCommand(s_InitCommands, sizeof(s_InitCommands), true); }
4.2.1.5. Processing Each Time Text Is Rendered
The processing performed until now is just initialization. This section describes the processing performed each time text is rendered.
The (Wide)TextWriter
classes perform the rendering of strings that have a specified display position and font color. An instance of this class is assumed to be generated each frame, so this class has no explicit initialization function. Classes that process tag characters are also configured by default, so as long as there is no need to process custom tag characters, you can use the generated instance with no changes required. In addition, if you set no buffer to receive the fully uncompressed and formatted string, and then call a formatted Printf()
function, 256 characters of memory is allocated from the stack. If you do not want to use the stack, or if a buffer with a capacity of more than 256 characters is needed, the application must allocate a buffer and set it using the SetBuffer()
function. The return value is a pointer to the previously set buffer.
The rendered strings are accumulated one character at a time as string display information. Use the SetDispStringBuffer()
function to set the buffer for accumulating string information. (This buffer was allocated in 4.2.1.3 Allocating a Display String Buffer) for the TextWriter
class. Use the SetFont()
function to set the font resources used in rendering.
The SetCursor
or MoveCursor()
functions are used to set the display position (that is, the cursor position). SetCursor
sets a new display position with no reference to a previous position. MoveCursor
specifies the display position relative to the previous position. The x, y, and z coordinates can be set individually, or they can all be set at the same time. The default is (0.0, 0.0, 0.0).
The SetDrawFlag()
function sets how the string is laid out in relation to the display position. This string layout is set by the bitwise OR of three flags: two flags (one each per vertical and horizontal axes) that specify where to place the origin of the rectangular region in which to render the string, and one flag (horizontal axis only) that specifies which direction to align or justify the string toward. The flags are defined by nn::font::PositionFlag
enumerators. The default string layout setting is HORIZONTAL_ALIGN_LEFT | HORIZONTAL_ORIGIN_LEFT | VERTICAL_ORIGIN_TOP
. Figure 4-3. illustrates how string layout changes as individual flags are changed from the default settings.
Characters are scaled up or scaled down with the SetScale()
or SetFontSize()
functions. SetScale
sets the width and height of characters as a multiple of the font’s width and height values. SetFontSize
sets pixel values for the width and height of the characters to display. Scaling also affects the ascent and descent. For this reason, the GetFontAscent
and GetFontDescent()
functions might return different values than those of the font. The default scaling is 100% (no change).
The SetTextColor()
function sets the character color. In addition, the SetGradationMode()
function can apply color gradation effects in the horizontal or vertical directions. The SetColorMapping()
function can set a linear transform for the gradation effect, and the gradation’s change in color can also be reversed depending on its settings. Note that the SetAlpha()
function can set an additional alpha value separate from the character color. The default settings are: a character color of (255
,255
,255
,255
), no gradation effect, no linear transform, and an additional alpha value of 255
.
The SetLineHeight()
function sets the height of one line. This setting automatically adjusts the line spacing, not the linefeed width. Use the SetLineSpace()
function to directly set the line spacing. Additionally, the SetTabWidth()
and SetCharSpace()
functions set the tab width and character spacing, respectively. The default settings are: 0
for the line spacing and character spacing, and a tab width of 4
characters wide.
To forcibly render strings at a fixed width and ignore the font’s settings, use the SetFixedWidth()
function to set the rendering width, and use EnableFixedWidth(true)
to enable monospaced rendering. Specify false
in the EnableFixedWidth()
function to again disable monospaced rendering. The default setting is false
(disabled).
The settings discussed until now are related to the display of text, and are set for the TextWriter
class. Graphics-related settings for rendering text are set for the RectDrawer
class.
The DrawBegin()
function performs the initialization required to begin rendering. This function generates rendering commands that initialize the render mode, textures, and other items. This function also initializes internal variables, so if you plan to set the parallax with the SetParallax()
function, you must do so after this function is called.
Set the projection matrix and view matrix with the SetProjectionMtx()
function and SetViewMtxForText()
function, respectively. The Font library assumes that the projection matrix has its origin at the upper left, with the dimensions of the screen in screen space identical to those of the LCD screen, and the positive directions of the y-axis and z-axis are reversed from their sign conventions in the CTR coordinate system. The view matrix is assumed to be a unit matrix.
Strings are rendered by the TextWriter
class. When characters are rendered, they are temporarily accumulated in the display string buffer as string display information, and the RectDrawer
class generates rendering commands from the accumulated information.
Use the TextWriter::StartPrint()
function to declare the start of string rendering. When this is done, the display string buffer is cleared.
Render strings using either the TextWriter::Print
or TextWriter::Printf()
function. The former does not specify a format string, while the latter does specify a format string.
When string rendering is complete, use the TextWriter::EndPrint()
function to declare the end of string rendering. Thereafter, the RectDrawer::BuildTextCommand()
function generates rendering commands based on the accumulated information and the TextWriter::UseCommandBuffer()
function sends the rendering commands to the command buffer.
Finally, call the RectDrawer::DrawEnd()
function to kick off the rendering commands and actually render the characters in the render buffer.
If there is no change to the content or display position of the string to render, you can get the same rendering results without any need to execute again the sequence of functions from the TextWriter::StartPrint()
function to the TextWriter::EndPrint()
and RectDrawer::BuildTextCommand()
functions. You can also render a string again and change only the character color, as long as the string was previously rendered in a solid color. However, this is possible only if the accumulated string display information has been saved.
The following code is the relevant portion of the sample demo.
//--------------------------------------------------------------------------- //! @brief Sets the modelview matrix and projection matrix for the display string. //! //! @param[in] pDrawer Pointer to the RectDrawer object. //! @param[in] width Screen width. //! @param[in] height Screen height. //--------------------------------------------------------------------------- void SetupTextCamera( nn::font::RectDrawer* pDrawer, int width, int height ) { // Set the projection matrix to orthogonal projection. { // Set as the upper-left origin, with the y-axis and z-axis in the reverse orientation. nn::math::MTX44 proj; f32 znear = 0.0f; f32 zfar = -1.0f; f32 t = 0; f32 b = static_cast<f32>(width); f32 l = 0; f32 r = static_cast<f32>(height); nn::math::MTX44OrthoPivot( &proj, l, r, b, t, znear, zfar, nn::math::PIVOT_UPSIDE_TO_TOP); pDrawer->SetProjectionMtx(proj); } // Set the modelview matrix to an identity matrix. { nn::math::MTX34 mv; nn::math::MTX34Identity(&mv); pDrawer->SetViewMtxForText(mv); } } //--------------------------------------------------------------------------- //! @brief Draw ASCII characters. //! //! @param[in] pDrawer Pointer to the RectDrawer object. //! @param[in] pDrawStringBuf Pointer to the DispStringBuffer object. //! @param[in] pFont Pointer to the font. //! @param[in] width Screen width. //! @param[in] height Screen height. //--------------------------------------------------------------------------- void DrawAscii( nn::font::RectDrawer* pDrawer, nn::font::DispStringBuffer* pDrawStringBuf, nn::font::ResFont* pFont, int width, int height ) { nn::font::TextWriter writer; writer.SetDispStringBuffer(pDrawStringBuf); writer.SetFont(pFont); writer.SetCursor(0, 0); // The strings are not changed, so the command for drawing strings is only created once. if (! s_InitAsciiString) { writer.StartPrint(); (void)writer.Print("DEMO: ResFont\n"); (void)writer.Print("\n"); // Display ASCII character samples (void)writer.Print("All ASCII Character listing:\n"); (void)writer.Print("\n"); (void)writer.Print(" !\"#$%&'()*+,-./\n"); (void)writer.Print("0123456789:;<=>?\n"); (void)writer.Print("@ABCDEFGHIJKLMNO\n"); (void)writer.Print("PQRSTUVWXYZ[\\\]^_\n"); (void)writer.Print("`abcdefghijklmno\n"); (void)writer.Print("pqrstuvwxyz{|}~\n"); writer.EndPrint(); pDrawer->BuildTextCommand(&writer); s_InitAsciiString = true; } // Character color can be changed without regenerating the string rendering commands. writer.SetTextColor(nn::util::Color8(s_Color, 255, s_Color, 255)); s_Color++; pDrawer->DrawBegin(); SetupTextCamera(pDrawer, width, height); writer.UseCommandBuffer(); pDrawer->DrawEnd(); }
4.2.1.6. Changing the GPU Settings With the Font Library
When fonts are rendered using the RectDrawer
class, various GPU settings are changed including the texture sampler type and the vertex attribute load addresses. For this reason, after rendering fonts, have the application validate all of the GPU states and reset all of the GPU settings, although in some cases this processing might be redundant.
This section describes the GPU settings configured when fonts are rendered, as reference material for reducing the cost of resetting the GPU.
Combiner Settings
Combiners 3 through 5 are used and set as follows. Some settings are different depending on whether the sheet’s texture format has an alpha component. Note also that the character color is expressed using the vertex color settings.
Setting | Color | Alpha |
---|---|---|
Source 0 |
GL_TEXTURE0
|
GL_TEXTURE0
|
Source 1 |
GL_CONSTANT
|
GL_CONSTANT
|
Source 2 |
GL_CONSTANT
|
GL_CONSTANT
|
Operand 0 |
(No alpha) (With alpha) |
GL_SRC_ALPHA
|
Operand 1 |
GL_SRC_COLOR
|
GL_SRC_ALPHA
|
Operand 2 |
GL_SRC_COLOR
|
GL_SRC_ALPHA
|
Combine |
GL_MODULATE
|
GL_MODULATE
|
Scale | 1.0 | 1.0 |
Constant color | White (1.0 , 1.0 , 1.0 , 1.0 ) |
Setting | Color | Alpha |
---|---|---|
Source 0 |
GL_TEXTURE0
|
GL_TEXTURE0
|
Source 1 |
GL_CONSTANT
|
GL_CONSTANT
|
Source 2 |
GL_PREVIOUS
|
GL_PREVIOUS
|
Operand 0 |
(No alpha) (With alpha) |
GL_ONE_MINUS_SRC_ALPHA
|
Operand 1 |
GL_SRC_COLOR
|
GL_SRC_ALPHA
|
Operand 2 |
GL_SRC_COLOR
|
GL_SRC_ALPHA
|
Combine |
GL_MULT_ADD_DMP
|
GL_MULT_ADD_DMP
|
Scale | 1.0 | 1.0 |
Constant color | Black (0.0 , 0.0 , 0.0 , 0.0 ) |
Setting | Color | Alpha |
---|---|---|
Source 0 | GL_PRIMARY_COLOR | GL_PRIMARY_COLOR |
Source 1 | GL_PREVIOUS | GL_PREVIOUS |
Source 2 | GL_PREVIOUS | GL_PREVIOUS |
Operand 0 | GL_SRC_COLOR | GL_SRC_ALPHA |
Operand 1 | GL_SRC_COLOR | GL_SRC_ALPHA |
Operand 2 | GL_SRC_COLOR | GL_SRC_ALPHA |
Combine | GL_MODULATE | GL_MODULATE |
Scale | 1.0 | 1.0 |
Constant color | Not yet set. Undefined. |
Reserved Fragment Shader Settings
The settings of the following reserved fragment shader features are changed.
Feature | Setting |
---|---|
Per-fragment operations mode | Standard mode (GL_FRAGOP_MODE_GL_DMP ) |
Fragment lighting | Disabled |
Shadows (shadow textures) | Disabled |
Fog ( and gas) | Disabled |
Alpha test | Disabled |
Blending | Enabled |
Texture Settings
Only texture 0 is used, and it is set to GL_TEXTURE_2D
. The texture image address and resolution, and filter settings and other settings are changed.
Shader Settings
Data required for rendering is set in the integer register i0 and the floating-point constant registers c0 through c95.
The shader program outputs the vertex coordinates, vertex color, texture coordinate 0, texture coordinate 1, and texture coordinate 2, but geometry shaders cannot be used.
4.2.2. Customizing the Processing of Tag Characters
By customizing classes that inherit the nn::font::TagProcessorBase
class, it is possible to implement custom processing of tag characters (0x0000
to 0x001F
).
When a tag character appears as a character to render in the middle of rendering a string, the TextWriter
class passes the character to the TagProcessor
class set in the TextWriter
for processing. By default, the TextWriter
class is configured to have a TagProcessor
class that processes the tab character (0x0009
) and the newline character (0x000A
), but you can use the SetTagProcessor()
function to set a customized TagProcessor
class.
When you use customized tag character processing, override the Process()
and CalcRect()
functions.
virtual Operation Process( u16 code, PrintContext<CharType>* pContext); virtual Operation CalcRect(util::Rect* pRect, u16 code, PrintContext<CharType>* pContext);
The TextWriter
class adjusts the coordinates at which to render characters based on the values returned from these functions. Implement your application so that the Process()
and CalcRect()
functions both return the same value when they process the same tag character.
Definition | Processing Performed by TextWriter |
---|---|
OPERATION_DEFAULT
|
Inserts no space before the next character if it is the first character in a line, but otherwise always inserts space before the next character. |
OPERATION_NO_CHAR_SPACE
|
Never inserts a space before the next character. |
OPERATION_CHAR_SPACE
|
Always inserts a space before the next character. |
OPERATION_NEXT_LINE
|
Performs newline processing. Only adjusts the x-coordinate; the y-coordinate must be adjusted when processing tags. |
OPERATION_END_DRAW
|
Ends string rendering in the middle of a string. |
A pointer to the TextWriter
class is included in the members of the pContext
argument, so it is possible to use tag characters for special processing, such as changing the character color.