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.
- Supported filters:
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 ofborder-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
andFilterInstancer
, 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:
Masking principles and demonstration:
Improved clipping behavior of nested and transformed elements (also showing improved layouting of positioned boxes):
Improved clipping 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.
- In your legacy RenderInterface implementation, derive from
Rml::RenderInterfaceCompatibility
instead of
Rml::RenderInterface
.#include <RmlUi/Core/RenderInterfaceCompatibility.h> class MyRenderInterface : public Rml::RenderInterfaceCompatibility { ... };
- 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.
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!
- Certain properties cause the element to establish a new BFC, such as overflow != visible, and the new
- 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.
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.
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.
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 propertiesjustify-content
andalign-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:
- Adding the library as a subdirectory directly from CMake.
- Building the library "in-source" without installing.
- Building and installing the library.
- 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 isbitmap_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 shorthandnav
. - 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
anddir
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:
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 theTextInputHandler
interface for IME support. - Add native IME support to Win32 backends (
Win32_GL2
andWin32_VK
). - Add new sample
rmlui_sample_ime
to demonstrate IME support (only enabled on supported backends).
- The text input widget implements the new
- 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:
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
option
s. #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
- Add CMake option
RMLUI_LUA_BINDINGS_LIBRARY
to link to the Lua library compiled as C++, or to LuaJIT. #604 (thanks @LiquidFenrir) - Add
StopImmediatePropagation
to Rml::Event. #466 (thanks @ShawnCZek) - Return inserted element from
AppendChild
andInsertBefore
. #478 (thanks @ShawnCZek)
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
andFormatString
methods no longer take amax_size
argument, as this is now handled automatically.- Allow using
margin
to offset thescrollbarcorner
. - 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, likeEASTL::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 usingRMLUI_TRACY_MEMORY_PROFILING
.
- Added CMake options for enabling (1) a separate configuration in multi-config mode with
- 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 theline-height
property.
- Possible solutions: Adjust the
- 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.
- Add
- 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
.
- Set the parent to use overflow != visible to establish a new block formatting context, or use the new
- Paint order on some elements may have changed.
- Change the tree order, or the
z-index
orclip
properties as appropriate.
- Change the tree order, or the
- Size of shrink-to-fit boxes may have changed.
- Position of documents with margins may have changed.
- Documents that don't have their size set will now shrink to their contents, previously they would span the entire context.
- The size can be set either directly using the
width
andheight
properties, or implicitly by a combination of thetop
/right
/bottom
/left
properties.
- The size can be set either directly using the
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 andProperty
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 aSpan
instead of a raw pointer. - Replaced
Element::ResolveNumericProperty
withElement::ResolveLength
andElement::ResolveNumericValue
. Can be used together withProperty::GetNumericValue
. - Renamed and removed several
Math
functions. - Removed the
max_size
argument fromCreateString
andFormatString
methods, this is no longer needed.
RCSS
- The old
gradient
decorator has been deprecated, instead one can now usehorizontal-gradient
andvertical-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
- @reworks-org made their first contribution in #449
- @aimoonchen made their first contribution in #463
- @gleblebedev made their first contribution in #475
- @viseztrance made their first contribution in #493
- @NaLiJa made their first contribution in #522
- @exjam made their first contribution in #546
- @LucidSigma made their first contribution in #563
- @Paril made their first contribution in #564
- @alml made their first contribution in #559
- @skaarj1989 made their first contribution in #579
- @pgruenbacher made their first contribution in #589
- @LiquidFenrir made their first contribution in #604
- @ChrisFloofyKitsune made their first contribution in #621
- @ben-metzger-z made their first contribution in #629
Full Changelog: 5.1...6.0