Skip to content

RmlUi 6.0

Latest
Compare
Choose a tag to compare
@github-actions github-actions released this 26 Aug 20:57
· 12 commits to master since this release

RmlUi 6.0 comes with some of the most visible changes so far, being the biggest release to date. It has taken its time, and I am very happy to finally release it into the wild! The release brings a good selection of smaller and larger goodies for everyone. I want to particularly emphasize three major changes:

  • Advanced rendering effects
  • Major layout engine improvements
  • CMake modernization

The advanced rendering effects include support for the box-shadow, filter, backdrop-filter, and mask-image properties from CSS. We also have support for all the CSS gradients, which can be used in our decorator system and as image masks. With these features you should have the tools to really make those elements pop. These additions also include more subtle but important changes, like making elements with border radius actually clip to the curved border. This has been a large undertaking, I started this work over two years ago, and it has been steadily (and sometimes not so steadily) worked on since then, with a lot of iterations on the implementation and API. Feedback from users during this process has been invaluable! I am quite happy with the end result, and it's nice to see this work finally being released.

For now, only the OpenGL 3 renderer has built-in support for the new effects. The other backends have been updated for the new API, but only support the old feature set. To support all of these features, the render interface needed a thorough update. At the same time, we took this opportunity to simplify and modernize the interface. So please be sure to check the breaking changes if you are upgrading with a custom render interface. We have made sure to make the new advanced effects optional, so you can start with the basics and opt-in to new functions incrementally as you want to expand your supported RCSS feature set.

The layout engine improvements are the very opposite of the advanced effects, they are hidden underneath in the library, not really visible to the end user. Nonetheless, this has been another massive undertaking. The inline layout part of the engine has been rewritten from scratch, and other large parts have been re-architectured. This change improves a lot of subtle layout issues, in the end over a hundred CSS tests have been fixed, and many long standing issues resolved. It also creates a foundation which will make it a lot easier to make changes and fix issues in the future. You can see some screenshots and comparisons to web browsers in the detailed release notes below. This change was in fact merged into master over a year ago. In this case, I am quite pleased that there has not been a lot of reports about it. I take that as an indication that your projects kept working pretty much the same, despite the massive changes underneath. Do expect some layout changes when upgrading from the previous release though, details and solutions are posted below.

Our CMake implementation really used to be a patch-work with an ancient foundation. It was time for a complete rewrite. Special thanks to @hobyst who initiated and layed the groundwork for the new implementation following modern guidelines. It should now be a lot easier to build the library and link to it. This does however involve changes to pretty much all options, targets, and executable names, so be sure to check the detailed release notes below to migrate your existing project.


I want to give a sincere thanks to all the contributors, and everyone active in the community. A lot of effort has been put into the library from a lot of people. Many of the changes in this release come directly from you, and your feedback helps improve the quality of the library. It has almost been a bit hard for me to keep up with everything and to respond as fast as I'd like. But I also need to give myself some breathers from time to time, and contribute with the amount I can.

In addition to all the contributors mentioned in the release notes below, I also want to give a special mention to contributors to the documentation: @ShawnCZek, @viseztrance, @Paril, @LucidSigma, and @slipher. No feature is complete without good documentation, so I appreciate all the help I can get here!

Finally, I want to give a thanks to everyone who contributed with pull requests that in the end didn't end up being merged. Even if they weren't merged, they bring valuable discussion and ideas: @CreatorInDeep, @blaisemccourtney, @JailbreakPapa, @skaarj1989, and @exjam.

I am very much looking forward to seeing what you build with this, have fun! Feel free to share your results with us, either on the gitter chat or in the discussions.

The detailed changelog follows below. Projects coming from previous releases should take a look at the breaking changes, which include tips for migration. The documentation is updated to reflect all the changes in this release.

RmlUi 6.0 Changelog

Table of contents. Turns out linked headers do not work in release notes, but I leave an unlinked version here for a quick overview.

  • Advanced rendering features
    • New features
    • Screenshots
    • Major overhaul of the render interface
    • Backward compatible render interface adapter
    • Render manager and resources
    • Limitations
  • Major layout engine improvements
    • Detailed layout improvements
    • Layout comparisons
    • General layout improvements
  • CMake modernization
    • New target names
    • New library filenames
    • New option names
    • New exported definitions
    • CMake presets
  • Spatial navigation
  • Text shaping and font engine
  • Elements
  • Text input widget
  • Utilities
  • Data bindings
  • Debugger plugin
  • Lua plugin
  • System interface
  • General improvements
  • General fixes
  • Build improvements
  • Backends
  • Breaking changes
    • CMake and linking
    • Layout
    • Elements
    • Core types
    • Core functions
    • RCSS
    • Render interface
    • Render manager
    • Font engine interface
    • Removed deprecated functionality

Advanced rendering features

This one has been a long time in the making, now the time has come for one of the biggest additions to the library. Advanced rendering effects are now available, including filters with blur support, box-shadow, advanced gradients, shaders, masks, and clipping of rounded borders.

The original issue is found in #307 and the pull request is #594. Thanks to everyone who provided feedback. Resolves #249, #253, #307, #597, and even addresses #1.

New features

New properties:

  • filter: Apply a rendering effect to the current element (including its children).
    • Supported filters: blur, drop-shadow, hue-rotate, brightness, contrast, grayscale, invert, opacity, sepia. That is, all filters supported in CSS.
  • backdrop-filter: Apply a filter to anything that is rendered below the current element.
  • mask-image: Can be combined with any decorator, including images and gradients, to mask out any part of the current element (and its children) by multiplying their alpha channels.
  • box-shadow: With full support for offset, blur, spread, and insets.

New decorators:

  • shader: A generic decorator to pass a string to your renderer.
  • linear-gradient, repeating-linear-gradient
  • radial-gradient, repeating-radial-gradient
  • conic-gradient, repeating-conic-gradient

The gradients support most of the CSS features and syntax, including angle and to <direction> syntax for direction, multiple color stops, locations in length or percentage units, and up to two locations per color. Please see the decorators documentation for details.

  • The new rendering interface includes support for shaders, which enable the above decorators. Parsing is done in the library, but the backend renderer is the one implementing the actual shader code.

  • All filters and gradient decorators have full support for interpolation, that is, they can be animated. This is not yet implemented for box shadows.

  • Decorators can now take an extra keyword <paint-area> which is one of border-box | padding-box | content-box. The keyword indicates which area of the element the decorator should apply to. All built-in decorators are modified to support this property. For example: decorator: linear-gradient(to top right, yellow, blue) border-box.

  • Custom filters can be created by users by deriving from Filter and FilterInstancer, analogous to how custom decorators are created.

  • Improved element clipping behavior. Handles more complicated cases, including nested transforms with hidden overflow, and clipping to the curved edge of elements with border-radius. This requires clip mask support in the renderer.

The documentation has been updated to reflect the new features, including the new decorators and properties, with examples and screenshots. The new features are also demonstrated in the new effects sample, so please check that out.

For now, only the OpenGL 3 renderer implements all new rendering features. All other backends have been updated to work with the updated render interface but with their old feature set. For users with custom backends, please see the updated render interface documentation in particular. Here, you will also find a table detailing exactly which functions must be implemented to support particular RCSS features.

Here are some quick RCSS examples taken from the documentation.

decorator: linear-gradient(to bottom, #00f3, #0001, #00f3), linear-gradient(to top right, red, blue);
decorator: radial-gradient(circle farthest-side at center, #ff6b6b, #fec84d, #4ecdc4);
decorator: repeating-conic-gradient(from 90deg, #ffd700, #f06, #ffd700 180deg);
decorator: shader("my_shader") border-box;

filter: brightness(1.2) hue-rotate(90deg) drop-shadow(#f33f 30px 20px 5px);
backdrop-filter: blur(10px);

box-shadow: #f008 40px 30px 0px 0px, #00f8 -40px -30px 0px 0px;
mask-image: conic-gradient(from 45deg, black, transparent, black), image("star.png" cover);

Screenshots

Collage of advanced effects:

Advanced effects demonstration

Masking principles and demonstration:

Mask imaging and demonstration

Improved clipping behavior of nested and transformed elements (also showing improved layouting of positioned boxes):

Clipping comparison of nested and transformed elements

Improved clipping with border-radius:

Clipping comparison of elements with border-radius

Demonstration of the effects sample:

effects.sample.-.2024-02-05.webm

Major overhaul of the render interface

The render interface has been simplified to ease implementation of basic rendering functionality, while extended to enable the new advanced rendering effects. The new effects are fully opt-in, and can be enabled iteratively to support the features that are most desired for your project. See the updated render interface documentation for how to implement the new functionality. The documentation includes a table detailing which functions must be implemented to support specific RCSS features.

Highlighted changes:

  • Now using safer, modern types (like span).
  • A clear separation between required functions for basic functionality, and optional features for advanced rendering effects. The required functions are now pure virtual.
  • All colors are now submitted as 8-bit sRGBA (like before), but with premultiplied alpha (new). Existing renderers should modify their blending modes accordingly. This change is central to correct blending of partially transparent layers.
  • All geometry is now compiled before it can be rendered, which helps to simplify the interface.
    • Now the pointers to the geometry data (vertices and indices) are guaranteed to be available and immutable until the same geometry is released. Thus, users can simply store the views to this data, and reuse that during rendering, which should help considerably for users migrating from the immediate rendering function.
  • The scissor region should now be applied separately from any active transform. Previously, we would have to manually redirect the scissor to a stencil operation, that is no longer the case. Instead, the clipping with transform is now handled by the library, and directed to the clip mask functionality of the render interface as appropriate.
  • Expanded functionality to enable the new rendering effects, including layered rendering, rendering to texture, rendering with filters and shaders.
  • Textures are no longer part of the compiled geometry, compiled geometry can be rendered with different textures or shaders.

Backward compatible render interface adapter

The render interface changes will require updates for all users writing their own render interface implementation. To smooth the transition, there is a fully backward-compatible adapter for old render interfaces, please see RenderInterfaceCompatibility.h.

  1. In your legacy RenderInterface implementation, derive from Rml::RenderInterfaceCompatibility instead of
    Rml::RenderInterface.
        #include <RmlUi/Core/RenderInterfaceCompatibility.h>
        class MyRenderInterface : public Rml::RenderInterfaceCompatibility { ... };
  2. Use the adapted interface when setting the RmlUi render interface.
        Rml::SetRenderInterface(my_render_interface.GetAdaptedInterface());

That's it, and your old renderer should now still work!

It can also be useful to take a closer look at the adapter before migrating your own renderer to the new interface, to see which changes are necessary. Naturally, this adapter won't support any of the new rendering features.

For demonstration purposes, there are two built-in backends implementing the adapter: BackwardCompatible_GLFW_GL2 and BackwardCompatible_GLFW_GL3. Each of the backends use a direct copy of their respective render interface from RmlUi 5.1, only with the above instructions applied. Please take a look if you want to see some examples on how to use this adapter.

Render manager and resources

A new RenderManager is introduced to manage resources and other rendering state. Users don't normally have to interact with this, but for contributors, and for more advanced usages, such as custom decorators, this implies several changes.

The RenderManager can be considered a wrapper around the render interface. All internal calls to the render interface should now go through this class.

Resources from the render interface are now wrapped as unique render resources, which are move-only types that automatically clean up after themselves when they go out of scope. This considerably helps resource management. This also implies changes to many central rendering types.

  • Mesh: A new type holding indices and vertices. Can be constructed directly or from MeshUtilities (previously GeometryUtilities).
  • Geometry: Is now a unique resource holding a compiled geometry handle, and constructed from a Mesh, taking ownership of the mesh's data.
  • Texture: Now simply a non-owning view and can be freely copied. The underlying file texture is owned by the render manager, and held throughout the manager's lifetime.
  • CallbackTexture: In contrast, this is a unique render resource, automatically released when out of scope.

See this commit message for more details.

Limitations

Filters will only render based on geometry that is visible on-screen. Thus, some filters may be cut off. As an example, an element that is partly clipped with a drop-shadow may have its drop-shadow also clipped, even if it is fully visible. On the other hand, box shadows should always be rendered properly, as they are rendered off-screen and stored in a texture.

Major layout engine improvements

  • Make layout more conformant to CSS specification.
    • Rewritten inline layout engine.
    • Fixed more than a hundred CSS tests, including ACID1.
  • Improve readability and maintainability:
    • Better separation of classes, reduce available state.
    • Make classes better conform to CSS terminology.
    • Improve call-graph, flow from parent to child, avoid mutable calls into ancestors.
  • Fix long-standing issues.
    • Allow tables and flexboxes to be absolutely positioned or floated.
    • Allow nested flexboxes: Flex items can now be flex containers themselves. #320
    • Better handling of block-level boxes in inline formatting contexts. #392

Detailed layout improvements

Here is a more detailed change list resulting from the rewritten inline formatting engine, and some related changes.

  • Corrected the baseline of fonts, they should now line up better.
  • Inline layout now properly uses font metrics as appropriate, even without any text contents.
    • In particular, vertical alignment now considers font ascent and descent.
    • This might make some lines taller. In particular, inline-level boxes that are placed on the baseline will now make space for the font descent below the baseline.
  • Improved baselines for inline-block boxes.
  • Content height of inline boxes no longer depend on their line-height property, only font metrics.
  • Block formatting contexts (BFC) now work like in CSS: Floated boxes share space and interact within the same BFC, and never outside of it.
    • Certain properties cause the element to establish a new BFC, such as overflow != visible, and the new display: flow-root value.
    • Milestone: We now pass ACID1!
  • Relative positioning now works in other formatting contexts and situations. #471
    • Including for inline, flex, table, and floated elements, in addition to block boxes like before.
    • Also, nested relative elements are now correctly positioned.
  • Containing blocks are now determined more like in CSS, particularly for absolute elements.
    • Only elements which are positioned, or with local transform or perspective, establishes an absolute containing block.
  • An overflowing element's scroll region no longer has its padding added to the region.
    • Elements are checked for overflowing the padding box instead of the content box, before enabling scrollbars.
    • The border box of floats will now be considered for overflow, instead of their margin box.
  • Fix some replaced elements (e.g. textarea) not rendering correctly in several situations, such as when set to block display, floated, or absolutely positioned.
  • Improve shrink-to-fit width, now includes floating children when determining width.
  • Margins of absolutely positioned elements now better account for inset (top/right/bottom/left) properties.
  • Support for new display values: flow-root, inline-flex, inline-table.
  • Support for the value vertical-align: center.
  • Stacking contexts are now established in a way that more closely aligns with CSS.
  • Improve the paint order of elements.
    • Render all stacking context children after the current element's background and decoration. This change is consistent with the CSS paint order. Additionally, it leads to simpler code and less state change, particularly when combined with the advanced rendering effects.

Please see the list of breaking changes and solutions at the end of the changelog.

Layout comparisons

Here are some screenshots demonstrating the layout improvements.

inline-formatting-01-mix

The above example demonstrates a variety of inline formatting details, with nested elements and borders (fiddle). We now match nicely with web browsers in such situations. The old behavior has several issues, in particular the elements are not aligned correctly and the border is broken off too early. Note that Firefox in these examples uses a different font, so expect some differences for that reason.

inline-formatting-04-mix

The above shows tests for line splits and borders in particular (fiddle). The old behavior is almost comically broken. The new behavior has for the most part been written from scratch following the CSS specifications, and turns out to nicely match up with Firefox.

inline-formatting-aligned-subtree

Finally, this example tests vertical alignment of inline boxes, and particularly the concept of aligned subtrees (fiddle). Again, we now nicely align with Firefox. The old behavior looks like it just gave up in the middle. I included Chrome here too, since I find it interesting how different it behaves compared to Firefox. In fact, I found a lot of these differences while testing various nuances of inline formatting. In this case, I am quite convinced that Firefox (and we) are doing the right thing and Chrome is not following the specifications.

General layout improvements

  • Scale pixels-per-inch (PPI) units based on the context's dp-ratio. #468 (thanks @Dakror)
  • Make flex containers and tables with fixed width work in shrink-to-fit contexts. #520
  • Compute shrink-to-fit width for flex boxes. #559 #577 (thanks @alml)
  • Add the space-evenly value to flex box properties justify-content and align-content. #585 (thanks @LucidSigma)
  • Implement the gap property for flexboxes. #621 (thanks @ChrisFloofyKitsune)
  • Flexbox: Consider intrinsic sizes when determining flex base size, fixes an assertion error. #640

CMake modernization

The CMake code has been fully rewritten with modern practices. Special thanks to @hobyst who laid the groundwork for this change, with a solid foundation and great guidelines. #198 #446 #551 #606 (thanks @hobyst)

While modernizing our CMake code, it was clear that we also needed to change our naming conventions. This leads to quite significant breaking changes for building and linking, but the result should make the library a lot easier to work with and link to.

We now try to support all setups including:

  1. Adding the library as a subdirectory directly from CMake.
  2. Building the library "in-source" without installing.
  3. Building and installing the library.
  4. Using pre-built Windows binaries.

It should be a lot easier now to simply point to the built library or sources, and have everything link correctly.

And naturally, we will continue to support package managers however we can, and that is still considered the default recommendation. However, for the most part we rely on contributors to keep supporting this. Please help out with your favorite package manager if you see missing versions, or room for improvements.

Large parts of the CI workflows have also been rewritten to accommodate these changes. Most of the Windows building and packaging procedures have been moved from Appveyor to GitHub Actions, which streamlines our testing and also helps speed up the CI builds.

The build documentation has been updated to reflect all the new changes.

New target names

We now export the following targets:

Target Old target Description
RmlUi::RmlUi Includes all sub-libraries of the project, as listed just below
RmlUi::Core RmlCore The main library
RmlUi::Debugger RmlDebugger The debugger library
RmlUi::Lua RmlLua The Lua plugin (when enabled)

When including RmlUi as a subdirectory, the targets are constructed as aliases. When using pre-built or installed binaries, they are constructed using imported targets, which are available through the exported build targets.

The internal target names have also been changed, although they are typically only needed when exploring or developing the library. They are all lowercase and contain the prefix rmlui_ to avoid colliding with names in any parent projects. Some examples are: rmlui_core, rmlui_debugger, rmlui_sample_invaders, rmlui_tutorial_drag, rmlui_unit_tests, and rmlui_visual_tests.

New library filenames

The library binaries have also changed names. These names would be suffixed by e.g. .dll on Windows, and so on.

Library Old library Description
rmlui RmlCore The core (main) library
rmlui_debugger RmlDebugger The debugger library
rmlui_lua RmlLua The Lua plugin (when enabled)

New option names

We have a new set of CMake naming conventions for the library:

  • Use RMLUI_ prefix to make all options specific to this project easily identifiable, and avoid colliding with any parent project variables.
  • Do not include negations (such as "not" and "disable"), to avoid situations with double negation.
  • Do not include a verb prefix (such as "enable" and "build"), as these are often superfluous.

The following table lists all the new option names.

Option Default value Old related option Comment
RMLUI_BACKEND auto SAMPLES_BACKEND
RMLUI_COMPILER_OPTIONS ON Automatically sets recommended compiler flags
RMLUI_CUSTOM_CONFIGURATION OFF CUSTOM_CONFIGURATION
RMLUI_CUSTOM_CONFIGURATION_FILE CUSTOM_CONFIGURATION_FILE
RMLUI_CUSTOM_INCLUDE_DIRS CUSTOM_INCLUDE_DIRS
RMLUI_CUSTOM_LINK_LIBRARIES CUSTOM_LINK_LIBRARIES
RMLUI_CUSTOM_RTTI OFF DISABLE_RTTI_AND_EXCEPTIONS No longer modifies compiler flags - only enables RmlUi's custom RTTI solution so that the user can disable language RTTI and exceptions
RMLUI_FONT_ENGINE freetype NO_FONT_INTERFACE_DEFAULT Now takes a string with one of the options: none, freetype
RMLUI_HARFBUZZ_SAMPLE OFF
RMLUI_INSTALL_RUNTIME_DEPENDENCIES ON Automatically install runtime dependencies on supported platforms (e.g. DLLs)
RMLUI_LOTTIE_PLUGIN OFF ENABLE_LOTTIE_PLUGIN
RMLUI_LUA_BINDINGS OFF BUILD_LUA_BINDINGS
RMLUI_LUA_BINDINGS_LIBRARY lua BUILD_LUA_BINDINGS_FOR_LUAJIT Now takes a string with one of the options: lua, lua_as_cxx, luajit
RMLUI_MATRIX_ROW_MAJOR OFF MATRIX_ROW_MAJOR
RMLUI_PRECOMPILED_HEADERS ON ENABLE_PRECOMPILED_HEADERS
RMLUI_SAMPLES OFF BUILD_SAMPLES
RMLUI_SVG_PLUGIN OFF ENABLE_SVG_PLUGIN
RMLUI_THIRDPARTY_CONTAINERS ON NO_THIRDPARTY_CONTAINERS
RMLUI_TRACY_CONFIGURATION ON New option for multi-config generators to add Tracy as a separate configuration.
RMLUI_TRACY_MEMORY_PROFILING ON New option to overload global operator new/delete for memory inspection with Tracy.
RMLUI_TRACY_PROFILING OFF ENABLE_TRACY_PROFILING
- VISUAL_TESTS_CAPTURE_DIRECTORY Replaced with environment variable RMLUI_VISUAL_TESTS_CAPTURE_DIRECTORY
- VISUAL_TESTS_COMPARE_DIRECTORY Replaced with environment variable RMLUI_VISUAL_TESTS_COMPARE_DIRECTORY
- VISUAL_TESTS_RML_DIRECTORIES Replaced with environment variable RMLUI_VISUAL_TESTS_RML_DIRECTORIES

For reference, the following options have not changed names, as these are standard options used by CMake.

Unchanged options Default value
CMAKE_BUILD_TYPE
BUILD_SHARED_LIBS ON
BUILD_TESTING OFF

New exported definitions

Certain CMake options, when changed from their default value, require clients to set definitions before including RmlUi. These are automatically set when using the exported CMake targets, otherwise users will need to define them manually.

Some exported definition names have changed, as follows.

Definition Old definition Related CMake option
RMLUI_TRACY_PROFILING RMLUI_ENABLE_PROFILING RMLUI_TRACY_PROFILING
RMLUI_CUSTOM_RTTI RMLUI_USE_CUSTOM_RTTI RMLUI_CUSTOM_RTTI

For reference, here follows all other possibly exported definitions.

Definition Related CMake option
RMLUI_STATIC_LIB BUILD_SHARED_LIBS
RMLUI_NO_THIRDPARTY_CONTAINERS RMLUI_THIRDPARTY_CONTAINERS
RMLUI_MATRIX_ROW_MAJOR RMLUI_MATRIX_ROW_MAJOR
RMLUI_CUSTOM_CONFIGURATION_FILE RMLUI_CUSTOM_CONFIGURATION_FILE

CMake presets

We now have CMake presets:

  • samples Enable samples but only those without extra dependencies.
  • samples-all Enable all samples, also those with extra dependencies.
  • standalone Build the library completely without any dependencies, the only sample available is bitmap_font.
  • dev Enable testing in addition to samples.
  • dev-all Enable testing in addition to samples, including those that require extra dependencies.

The presets can be combined with other options, like CMAKE_BUILD_TYPE to select the desired build type when using single-configuration generators.

Spatial navigation

Introduce spatial navigation for keyboards and other input devices. This determines how the focus is moved when pressing one of the navigation direction buttons. #142 #519 #524 (thanks @gleblebedev)

  • Add the new properties nav-up, nav-right, nav-down, nav-left, and shorthand nav.
  • Add :focus-visible pseudo class as a way to style elements that should be highlighted during navigation, like its equivalent CSS selector.
  • The invaders sample implements this feature for full keyboard navigation, and uses :focus-visible to highlight the focus.
  • Elements in focus are now clicked when pressing space bar.

RCSS example usage:

input { nav: auto; nav-right: #ok_button; }
.menu_item { nav: vertical; border: #000 3px; }
.menu_item:focus-visible { border-color: #ff3; }

Text shaping and font engine

  • Add lang and dir RML attributes, along with text shaping support in the font engine interface. #563 (thanks @LucidSigma)
  • Create a sample for text shaping with Harfbuzz, including right-to-left text formatting. #568 #211 #588 (thanks @LucidSigma)
    • Implement fallback font support for the Harfbuzz sample. #635 (thanks @LucidSigma)
  • Add support for the letter-spacing property. #429 (thanks @igorsegallafa)
  • Add initialize and shutdown procedures to font engine interface for improved lifetime management. #583

Screenshots of the HarfBuzz sample showing Arabic text properly rendered with the HarfBuzz font engine, and compared to the default font engine:

HarfBuzz font engine vs default font engine comparison

Elements

  • Enable removal of properties using shorthand names. #463 (thanks @aimoonchen)
  • Add Element::Matches, the last missing selector-related function. #573 (thanks @Paril)
  • Element::GetInnerRML now includes the local style properties set on the element in the returned RML.
  • Tab set: Allow ElementTabSet::RemoveTab to work on tab sets with no panels. #546 (thanks @exjam)
  • Range input: Fix a bug where the bar position was initially placed wrong when using min and max attributes.

Text input widget

The following improvements apply to both the textarea and text input elements.

  • Add input method editor (IME) support. #541 #630 (thanks @ShawnCZek)
    • The text input widget implements the new TextInputContext interface, backends can interact with this by implementing the TextInputHandler interface for IME support.
    • Add native IME support to Win32 backends (Win32_GL2 and Win32_VK).
    • Add new sample rmlui_sample_ime to demonstrate IME support (only enabled on supported backends).
  • Add support for the text-align property in text inputs. #454 #455 (thanks @Dakror)
  • Fix clipboard being pasted when Ctrl + Alt + V key combination is used. #464 #465 (thanks @ShawnCZek)
  • Fix selection index possibly returning an invalid index. #539 (thanks @ShawnCZek)
  • Move the input cursor when the selection range changes. #542 (thanks @ShawnCZek)
  • Ignore selection range update when the element is not focused. #544 (thanks @ShawnCZek)
  • Text area elements now clip to their padding area instead of the content area, text input elements still clip to their content area (see 58581477 for details).
  • Improve text widget navigation and selection (see be9a497b for details).
  • The text cursor is no longer drawn when selecting text.
  • Consume key events with modifiers (ctrl, shift) to prevent event propagation and subsequently performing navigation.
  • Fix some cases where the scroll offset would alternate each time the text cursor was moved, causing rendering to flicker.
  • Use rounded line height to make render output more stable when scrolling vertically.

IME sample screenshot:

IME sample screenshots

Utilities

  • Improved mesh utilities to construct background geometry for any given box area of the element, including for elements with border-radius, see MeshUtilities.h.
  • New Rectangle type to better represent many operations.
  • Visual tests:
    • Several new visual tests for the new features.
    • Highlight differences when comparing to previous capture by holding shift key.
    • Replace CMake options with environment variables.

Data bindings

  • Enable arbitrary expressions in data address lookups. #547 #550 (thanks @Dakror and @exjam)
  • Add enum support to variants and data bindings. #445 (thanks @Dakror)
  • Allow nested data models. #484 (thanks @Dakror)
  • Fix XML parse error if single curly brace encountered at the end of a data binding string literal. #459 (thanks @Dakror)
  • Fix usage of data variables in selected options. #509 #510 (thanks @Dakror)

Debugger plugin

  • Display the axis-aligned bounding box of selected elements, including any transforms and box shadows (white box).
  • List box model sizes for the selected element.
  • Log an error message when externally closing documents owned by the debugger plugin.
  • Debugger now works with documents that have modal focus. #642

Lua plugin

System interface

  • The system interface is now optional. All functions now have a default implementation. Thus, it is no longer necessary to derive from and set this interface unless you want to customize its functionality.
  • The default log output is now used when there is no system interface installed. All print-like calls, including those in backends, are now submitted to the built-in logger.
  • Fix the JoinPath method so that it is passed through when using the debugger plugin. #462 #603 (thanks @Dakror)

General improvements

  • Add repeat fit modes to the image decorator, e.g. decorator: image(alien.png repeat). #259 #493 (thanks @viseztrance)
  • Implement the ability to release specific textures from memory using Rml::ReleaseTexture. #543 (thanks @viseztrance)
  • Add support for the not prefix in media queries. #564 (thanks @Paril)
  • Use string parser to allow "quotes" in sprite sheet src property. #571 #574 (thanks @andreasschultes)
  • Format color types using RCSS hexadecimal notation.
  • CreateString and FormatString methods no longer take a max_size argument, as this is now handled automatically.
  • Allow using margin to offset the scrollbarcorner.
  • Log a warning when a texture could not be loaded.
  • Improve text culling.
    • Previously, the text could be culled (that is, not rendered) even if it was visible due to transforms bringing it into view. Now, text culling properly considers the transform of the element.
    • The text is now culled when the element is outside the viewport even if no scissor region is active.

General fixes

  • Fix wrong logic for assertion of released textures. #589 (thanks @pgruenbacher)
  • Fix in-source documentation in Factory. #646 (thanks @ben-metzger-z)
  • Fix some situations where the scroll offset of an element would reset or change after layout updates. #452
  • Fix some situations where units were not shown in properties, now all invoked types are ensured to define a string converter.
  • In demo sample, fix form submit animation not playing smoothly on power saving mode.
  • Fix crash on shutdown in bitmap_font sample.
  • Fix being able to drag through the scroll track of a scrollbar.
  • Fix being able to scroll in a direction with hidden overflow.

Build improvements

  • Fix compilation issues on newer Clang and GCC releases due to mixed use of std namespace on standard integer types. #470 #545 #555
  • Fix UnitTests compilation error on MSVC by updating doctest. #491 (thanks @mwl4)
  • Fix Benchmarks compilation error when using custom string type. #490 (thanks @mwl4)
  • Change StringUtilities::DecodeRml to improve compatibility with other string types, like EASTL::string. #472 #475 (thanks @gleblebedev)
  • Various CMake fixes for MacOS. #525 (thanks @NaLiJa)
  • Fix include paths. #533 #643 (thanks @gleblebedev and @Paril)
  • Improve integration of the Tracy library in CMake. #516 #518
    • Added CMake options for enabling (1) a separate configuration in multi-config mode with RMLUI_TRACY_CONFIGURATION, and (2) the memory profiler by overriding global operators new/delete using RMLUI_TRACY_MEMORY_PROFILING.
  • Make test executables work with Emscripten.

Backends

  • OpenGL 3: Restore all modified state after rendering a frame. #449 (thanks @reworks-org)
  • OpenGL 3: Add depth test to OpenGL state backup. #629 (thanks @ben-metzger-z)
  • OpenGL 3: Set forward compatibility flag to fix running on MacOS. #522 (thanks @NaLiJa)
  • Vulkan: Several fixes for validation errors and flickering behavior. #593 #601 (thanks @wh1t3lord)
  • Vulkan: Update deprecated debug utilities. #579 (thanks @skaarj1989)
  • GLFW: Use new GLFW 3.4 cursors when available.
  • GLFW: Fix mouse position conversion to pixel coordinates, particularly on MacOS retina displays. #521
  • SDL: Use performance counters for increased time precision.
  • Win32: Center window in screen when opening it.

Breaking changes

CMake and linking

  • Most options, target names, library filenames, and certain exported definitions, have been changed. Please see the tables above.
  • CMake minimum version raised to 3.10.

Layout

Expect some possible layout shifts in existing documents, mainly due to better CSS conformance. Detailed notes are available above. Here are some particular situations where layout output may change, and ways to address them:

  • Some lines may become taller, with extra spacing added below its baseline.
    • Possible solutions: Adjust the vertical-align property of any inline block elements on the line. For example, use top/center/bottom or manual vertical alignment. The line height itself can be adjusted with the line-height property.
  • Absolutely positioned elements may be placed relative to an element further up in the document tree.
    • Add position: relative on the desired ancestor to establish its containing block.
  • The containing block size may change in some situations, which could affect percentages in (min-/max-) height properties.
    • To establish a containing block size, make their parent have a definite (non-auto) height.
  • Some floated elements may have moved or now extend below parent boxes.
    • Set the parent to use overflow != visible to establish a new block formatting context, or use the new display: flow-root.
  • Paint order on some elements may have changed.
    • Change the tree order, or the z-index or clip properties as appropriate.
  • Size of shrink-to-fit boxes may have changed.
  • Position of documents with margins may have changed.

Elements

  • The text area element now clips to its padding area instead of the content area. You may want to adjust RCSS rules to account for this. If you use decorators to display borders for text areas, you can set the decorator paint area to border-box and add a transparent border, e.g. decorator: image(my-textarea-background) border-box; border: 4px transparent;.

Core types

  • Changed Box enums and Property units as follows, now using strong types:
    • Box::Area -> BoxArea (e.g. Box::BORDER -> BoxArea::Border, values now in pascal case).
    • Box::Edge -> BoxEdge (e.g. Box::TOP -> BoxEdge::Top, values now in pascal case).
    • Box::Direction -> BoxDirection (e.g. Box::VERTICAL -> BoxDirection::Vertical, values now in pascal case).
    • Property::Unit -> Unit (e.g. Property::PX -> Unit::PX).

Core functions

  • Changed the signature of LoadFontFace (from memory) to take a Span instead of a raw pointer.
  • Replaced Element::ResolveNumericProperty with Element::ResolveLength and Element::ResolveNumericValue. Can be used together with Property::GetNumericValue.
  • Renamed and removed several Math functions.
  • Removed the max_size argument from CreateString and FormatString methods, this is no longer needed.

RCSS

  • The old gradient decorator has been deprecated, instead one can now use horizontal-gradient and vertical-gradient, thereby replacing the keyword to indicate direction. Please also see the new gradient decorators (linear, radial, and conic) above.

Render interface

Affects all users with a custom backend renderer.

  • Signature changes to several functions, see notes above and the updated documentation.
  • See RenderInterfaceCompatibility notes above for an adapter from the old render interface.
  • Texture is no longer part of the CompileGeometry command, instead it is submitted with the Render... command(s).
  • The immediate rendering function has been removed in favor of the compiled geometry version.
    • However, data pointers to the compile function are now stable, which should ease the transition.
  • Implementing the new clip mask API is required for handling clipping of transformed elements.
  • RmlUi now provides vertex colors and generated texture data in premultiplied alpha.
    • Set the blend mode to handle them accordingly. It is recommended to convert your own textures to use premultiplied alpha. This ensures correct compositing, especially with layers and effects.
  • Font effect color output now assumes premultiplied alpha. Color channels are initialized to black (previously white).

Render manager

Affects users with custom decorators and other more advanced usage with rendering commands.

  • RenderManager should now be used for all rendering instead of directly calling into the render interface.
  • Redefine Geometry, introduce Mesh.
    • Mesh is used to define vertices and indices, before it is submitted to construct a Geometry through the render manager.
    • Geometry is now a wrapper around the underlying geometry (to be) submitted to a render interface.
      • Move-only type which automatically releases its underlying resource when out of scope.
    • GeometryUtilities (class and header file) renamed to MeshUtilities.
      • Signatures changed to operate safely on a mesh instead of using raw pointers.
    • Geometry no longer stores a Texture, it must be submitted during rendering.
  • Redefine Texture.
    • This class is now simply a non-owning view of either a file texture or a callback texture.
    • CallbackTexture is a uniquely owned wrapper around such a texture.
    • These are constructed through the render manager.
    • File textures are owned by and retained by the render manager throughout its lifetime, released during its destruction.
  • Decorator interface: GenerateElementData has a new paint area parameter.
  • Moved DecoratorInstancer into the Decorator files.

Font engine interface

The font engine interface has been reworked to encompass new features, to simplify, and to modernize.

  • Font metrics are now collected into a single function.
  • Signature changes due to text shaping and letter-spacing support.
  • The active render manager is now passed into the appropriate functions to generate textures against this one.
  • Now using span and string view types where appropriate.

Removed deprecated functionality

  • Removed the <datagrid> and <dataselect> elements, related utilities, and associated tutorials. Users are encouraged to replace this functionality by tables, select boxes, and data bindings.

New Contributors

Full Changelog: 5.1...6.0