Skip to content

Commit

Permalink
[Complex Text Layouts] Update tutorials and documentation to match Te…
Browse files Browse the repository at this point in the history
…xtServer changes.
  • Loading branch information
bruvzg committed May 7, 2021
1 parent 3f60675 commit 20bcd13
Show file tree
Hide file tree
Showing 14 changed files with 1,483 additions and 68 deletions.
10 changes: 6 additions & 4 deletions about/list_of_features.rst
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,13 @@ Vulkan renderer.

- Hard or soft shadows.

- Font rendering using bitmaps (BitmapFont) or rasterization using FreeType (DynamicFont).
- Font rendering using bitmaps or rasterization using FreeType.

- Bitmap fonts can be exported using tools like BMFont.
- DynamicFont supports monochrome fonts as well as colored fonts.
- Dynamic fonts supports monochrome fonts as well as colored fonts.
Supported formats are TTF and OTF.
- DynamicFont supports optional font outlines with adjustable width and color.
- Dynamic fonts supports optional font outlines with adjustable width and color.
- Dynamic fonts supports variable fonts and OpenType features.
- Support for font oversampling to keep fonts sharp at higher resolutions.

- GPU-based particles with support for custom particle shaders.
Expand Down Expand Up @@ -437,7 +438,8 @@ Internationalization
or :ref:`gettext <doc_localization_using_gettext>`.
- Use localized strings in your project automatically in GUI elements or by
using the ``tr()`` function.
- Support for right-to-left typesetting and text shaping planned in Godot 4.0.
- Support for bidirectional typesetting and text shaping and OpenType localized forms.
- Automatic UI mirroring for right-to-left locales.

Windowing and OS integration
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
1,162 changes: 1,162 additions & 0 deletions classes/class_textserver.rst

Large diffs are not rendered by default.

111 changes: 111 additions & 0 deletions classes/class_textservermanager.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
:github_url: hide

.. Generated automatically by doc/tools/makerst.py in Godot's source tree.
.. DO NOT EDIT THIS FILE, but the TextServerManager.xml source instead.
.. The source is found in doc/classes or modules/<name>/doc_classes.
.. _class_TextServerManager:

TextServerManager
=================

**Inherits:** :ref:`Object<class_Object>`

Manager for the font and complex text layout servers.

Description
-----------

``TextServerManager`` is the API backend for loading, enumeration and switching :ref:`TextServer<class_TextServer>`\ s.

Note: Switching text server at runtime is possible, but will invalidate all fonts and text buffers. Make sure to unload all controls, fonts, and themes before doing so.

Methods
-------

+-------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`TextServer<class_TextServer>` | :ref:`find_interface<class_TextServerManager_method_find_interface>` **(** :ref:`String<class_String>` name **)** |const| |
+-------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`TextServer<class_TextServer>` | :ref:`get_interface<class_TextServerManager_method_get_interface>` **(** :ref:`int<class_int>` index **)** |const| |
+-------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`int<class_int>` | :ref:`get_interface_count<class_TextServerManager_method_get_interface_count>` **(** **)** |const| |
+-------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`int<class_int>` | :ref:`get_interface_features<class_TextServerManager_method_get_interface_features>` **(** :ref:`int<class_int>` index **)** |const| |
+-------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`String<class_String>` | :ref:`get_interface_name<class_TextServerManager_method_get_interface_name>` **(** :ref:`int<class_int>` index **)** |const| |
+-------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`Array<class_Array>` | :ref:`get_interfaces<class_TextServerManager_method_get_interfaces>` **(** **)** |const| |
+-------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`TextServer<class_TextServer>` | :ref:`get_primary_interface<class_TextServerManager_method_get_primary_interface>` **(** **)** |const| |
+-------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+
| :ref:`bool<class_bool>` | :ref:`set_primary_interface<class_TextServerManager_method_set_primary_interface>` **(** :ref:`int<class_int>` index **)** |
+-------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------+

Method Descriptions
-------------------

.. _class_TextServerManager_method_find_interface:

- :ref:`TextServer<class_TextServer>` **find_interface** **(** :ref:`String<class_String>` name **)** |const|

Finds an interface by its name.

----

.. _class_TextServerManager_method_get_interface:

- :ref:`TextServer<class_TextServer>` **get_interface** **(** :ref:`int<class_int>` index **)** |const|

Returns the interface registered at a given index.

----

.. _class_TextServerManager_method_get_interface_count:

- :ref:`int<class_int>` **get_interface_count** **(** **)** |const|

Returns the number of interfaces currently registered.

----

.. _class_TextServerManager_method_get_interface_features:

- :ref:`int<class_int>` **get_interface_features** **(** :ref:`int<class_int>` index **)** |const|

Returns text server supported features (binary OR).

----

.. _class_TextServerManager_method_get_interface_name:

- :ref:`String<class_String>` **get_interface_name** **(** :ref:`int<class_int>` index **)** |const|

Returns the interface name registered at a given index.

----

.. _class_TextServerManager_method_get_interfaces:

- :ref:`Array<class_Array>` **get_interfaces** **(** **)** |const|

Returns a list of available interfaces the index and name of each interface.

----

.. _class_TextServerManager_method_get_primary_interface:

- :ref:`TextServer<class_TextServer>` **get_primary_interface** **(** **)** |const|

Returns the primary :ref:`TextServer<class_TextServer>` interface.

----

.. _class_TextServerManager_method_set_primary_interface:

- :ref:`bool<class_bool>` **set_primary_interface** **(** :ref:`int<class_int>` index **)**

Sets (and initializes it if required) interface registered at a given index as the primary. Invalidates all references to the fonts and text buffers.

.. |virtual| replace:: :abbr:`virtual (This method should typically be overridden by the user to have any effect.)`
.. |const| replace:: :abbr:`const (This method has no side effects. It doesn't modify any of the instance's member variables.)`
.. |vararg| replace:: :abbr:`vararg (This method accepts any number of arguments after the ones described here.)`
4 changes: 4 additions & 0 deletions community/contributing/editor_and_docs_localization.rst
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,10 @@ The editor translations originate from C++ strings, and may use:
Scene '%s' is currently being edited.↵
Changes will only take effect when reloaded.

.. note::
Only logical order of the characters matters, in the right-to-left text, format
specifiers may be displayed as ``s%``.

Online documentation (RST)
^^^^^^^^^^^^^^^^^^^^^^^^^^

Expand Down
12 changes: 7 additions & 5 deletions getting_started/first_2d_game/06.heads_up_display.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,21 @@ Inspector. The default font for ``Control`` nodes is small and doesn't scale
well. There is a font file included in the game assets called
"Xolonium-Regular.ttf". To use this font, do the following:

1. Under "Custom Fonts", choose "New DynamicFont"
1. Under "Custom Fonts", choose "New Font"

.. image:: img/custom_font1.png

2. Click on the "DynamicFont" you added, and under "Font/Font Data", choose
"Load" and select the "Xolonium-Regular.ttf" file. You must also set the
font's ``Size``. A setting of ``64`` works well.
2. Click on the "Font" you added, and under "Font/Data/0",
choose "Load" and select the "Xolonium-Regular.ttf" file.

.. image:: img/custom_font2.png

Once you've done this on the ``ScoreLabel``, you can click the down arrow next
to the DynamicFont property and choose "Copy", then "Paste" it in the same place
to the Font property and choose "Copy", then "Paste" it in the same place
on the other two Control nodes.
Set "Custom Font Size" property of the ``ScoreLabel``. A setting of ``64`` works well.

.. image:: img/custom_font3.png

.. note:: **Anchors and Margins:** ``Control`` nodes have a position and size,
but they also have anchors and margins. Anchors define the origin -
Expand Down
Binary file modified getting_started/first_2d_game/img/custom_font1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified getting_started/first_2d_game/img/custom_font2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added getting_started/step_by_step/img/custom_font3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tutorials/i18n/img/bidi_override.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tutorials/i18n/img/icu_data.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tutorials/i18n/img/ui_mirror.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
69 changes: 69 additions & 0 deletions tutorials/i18n/internationalizing_games.rst
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,75 @@ called the :ref:`TranslationServer <class_TranslationServer>`.
Translations can be added or removed during run-time;
the current language can also be changed at run-time.

Bidirectional text and UI Mirroring
-----------------------------------

Arabic and Hebrew are written from right to left (except for the numbers and Latin
words mixed in), and the user interface for these languages should be mirrored as well.
In some languages the shape of a glyph changes depending on the surrounding characters.

Support for bidirectional writing systems and UI mirroring is transparent, you don't
usually need to change anything or have any knowledge of the specific writing system.

For RTL languages, Godot will automatically do the following changes to the UI:

- Mirrors left/right anchors and margins.
- Swaps left and right text alignment.
- Mirrors horizontal order of the child controls in the containers, and items in Tree/ItemList controls.
- Uses mirrored order of the internal control elements (e.g. OptionButton dropdown button, checkbox alignment, List column order, Tree item icons and connecting line alignment, e.t.c.), in some cases mirrored controls use separate theme styles.
- Coordinate system is not mirrored, and non-UI nodes (sprites, e.t.c) are not affected.x

It is possible to override text and control layout direction by using the following control properties:

- ``text_direction``, sets the base text direction. When set to "auto", direction depends on the first strong directional character in the text according to the Unicode Bidirectional Algorithm,
- ``language``, overrides current project locale.
- ``structured_text_bidi_override property`` and ``_structured_text_parser callback``, enables special handling for structured text.
- ``layout_direction``, overrides control mirroring.

.. image:: img/ui_mirror.png

Adding break iterator data to exported project
----------------------------------------------

Some languages are written without spaces, and word and line breaking requires more than rules over character sequences.
Godot includes ICU rule and dictionary based, break iterator data, but this data is not included into exported projects by default.
To include it go to **Project → Project Settings → Localization → Text Server Data** and click **Install support data...**. Break iterator data is about 4 MB large.

.. image:: img/icu_data.png

Structured text BiDi override
-----------------------------

Unicode BiDi algorithm is designed to work with natural text and it's incapable of
handling text with the higher level order, like file names, URIs, email addresses,
regular expressions or source code.

.. image:: img/bidi_override.png

For example, the path for this shown directory structure will be displayed incorrectly
(top "LineEdit" control). "File" type structured text override splits text into segments,
then BiDi algorithm is applied to each of them individually to correctly display directory
names in any language and preserve correct order of the folders (bottom "LineEdit" control).

Custom callbacks provide a way to override BiDi for the other types of structured text.

Localizing numbers
------------------

Controls specifically designed for number input or output (e.g. ProgressBar, SpinBox)
will use localized numbering system automatically, for the other control
:ref:`TextServer.format_number(string, language) <class_TextServer_method_format_number>`
can be used to convert Western Arabic numbers (0..9) to the localized numbering system
and :ref:`TextServer.parse_number(string, language) <class_TextServer_method_parse_number>`
to convert it back.

Localizing icons and images
---------------------------

Icons with left and right pointing arrows which may need to be reversed for Arabic
and Hebrew locales, in case they indicate movement or direction (e.g. back/forward
buttons), otherwise they can remain the same.

Command line
------------

Expand Down
Loading

0 comments on commit 20bcd13

Please sign in to comment.