Browse Source

Full CMake rewrite using modern CMake conventions

Partial rewrite originally written by @hobyst in #446 and #551.
Remaining code and changes written by @mikke89.

These changes should generally be feature-complete with the previous CMake code, with some exceptions to legacy and certain Apple-specific behavior. Please see the changelog for breaking changes, in particular, several options, CMake targets, and file names have been changed.

The following lists some noteworthy changes:

- CMake presets now available.
- Major changes to CI automation and tests.
  - Most tests on Appveyor are moved to Github actions. This includes a completely new packaging workflow on GitHub.
  - Packaging now uses Visual Studio 2019 instead of 2017. Keep Appveyor only for testing with Visual Studio 2017.
  - Use CMake scripts for some packaging tasks to avoid avoid duplicate workflow code.
- `RmlUi::RmlUi` is now an include-all library target, while components like `RmlUi::Core` and `RmlUi::Debugger` can be chosen individually.
- Add `contributing.md` guidelines for CMake.
- Backends can now be changed without recompiling the whole library.
- Set CMake `policy_max` to a recent version. This opts in to a number of CMake improvements for users that can take advantage of that.
- Sample bitmapfont now available without FreeType.
- Runtime outputs are now placed in the binary root directory.
- Runtime dependencies can now be installed automatically, this includes dependencies from vcpkg.
- Update .editorconfig and format all CMake files consistently.
- Rename `harfbuzzshaping` sample to `harfbuzz`.
- Fix harfbuzz compatibility for older versions.
- Remove CMake warning on FreeType version.

In the following, some working notes and lessons learned are written down (authored by @mikke89):

- Avoid separate libraries for subparts of Core

  Originally, parts of core such as Elements, Layout and FontEngineDefault, were added as interface libraries. Defining these as interface libraries cause issues during export. I believe we would have to export them as separate targets, but that doesn't relly make sense from a client standpoint and causes new issues with exported source files and dependencies. It seems to be a lot less troublesome to use a single CMake library and set properties and attach sources to that directly.

- Avoid interface libraries for plugins and Lua dependencies

  Using interface libraries to add plugins causes problems when installing targets. Even trying to split the interface libraries into private and public parts did not work suitably. An issue arises when compiling the project as static libraries. Consider when we are linking targets to rmlui_core. Even when they are added as private dependencies, CMake adds it as a transient link-time dependency. This even applies to interface dependencies, which causes problems for our private interface libraries representing the plugins. In particular, CMake wants us to export these libraries, as now they are referenced from rmlui_core, but we don't want to export them, as that was the whole point of making them private and would cause new issues.

  Instead, add the SVG and Lottie source files and imported dependencies directly to Core. This simplifies things quite a bit, and seems to work reliably. For similar reasons, use imported interface targets instead of a pure interface library for the custom Lua target.

- Common options for CMake targets

  Using CMake presets to specify compiler flags, warnings in particular, is not a great experience. Presets require one to set all the flags at the same time (in a single variable). For example, we can't easily set just /WX in one profile and /MP in another. There are workarounds, but being more pragmatic, setting these flags in a cmake file is much more straightforward with proper conditionals.

- On CMake presets

  I also experimented with more detailed, platform-dependent presets, but found that it is not really that useful. In particular, we want users themselves to use whichever compilers and generators they want to rather than to constrain the choices. We strive to be agnostict toward both generators and platforms. This way, we we can also give more common build instructions regardless of platform.

  Also tested with making presets for e.g. vcpkg and mingw toolchains. However, this doesn't really make sense in presets. First of all, the choice of such a toolchain is not mutually exclusive with the current presets, so we would have to replicate most of them for each toolchain we wanted to support. Further, the exact specifics of these toolcahins, like version, platform, install location, and so on, is very specific to each case. Thus, if we wanted to handle these it would create additional dimensions to the presets, and we'd end up with a huge list of similar presets we would have to mainatain and which users would have to choose from. Or alternatively, users would have to provide a lot of their setup in any case, thereby dismissing some of the initially considered usefulness. Instead, many tools already allow you to setup a toolchain first which can then be used with a given preset. Thus, making the choice of toolchains and cmake presets orthogonal makes a lot more sense.

  One unfortunate issue from a user-friendliness perspective is that the cmake gui doesn't allow you to select a preset without a specified generator. There's an issue for this here: https://gitlab.kitware.com/cmake/cmake/-/issues/23341
  I figured accepting this for now is better than duplicating all our presets to specify different generators. But the situations is not ideal, hopefully it will be fixed soon.

- Recommended compiler flags

  The compiler flags are enabled by default to ensure users get a good experience when building the library without fiddling with options. Especially on MSVC, the default compiler flags means really slow builds (no /MP), and we also risk exposing more warnings.

Co-authored-by: Michael Ragazzon <[email protected]>
hobyst 2 years ago
parent
commit
bbdb6e9c43
100 changed files with 3088 additions and 3570 deletions
  1. 12 111
      .appveyor.yml
  2. 7 1
      .editorconfig
  3. 95 53
      .github/workflows/build.yml
  4. 208 0
      .github/workflows/package.yml
  5. 8 0
      .gitignore
  6. 191 0
      Backends/CMakeLists.txt
  7. 33 0
      CMake/BackendAutoSelection.cmake
  8. 0 142
      CMake/BackendFileList.cmake
  9. 107 0
      CMake/Dependencies.cmake
  10. 169 0
      CMake/DependenciesForBackends.cmake
  11. 37 0
      CMake/DependenciesForShell.cmake
  12. 24 0
      CMake/DependenciesForTests.cmake
  13. 0 597
      CMake/FileList.cmake
  14. 63 0
      CMake/Modules/Emscripten/FindFreetype.cmake
  15. 84 0
      CMake/Modules/Emscripten/FindOpenGL.cmake
  16. 66 0
      CMake/Modules/Emscripten/FindSDL2.cmake
  17. 82 0
      CMake/Modules/Emscripten/FindSDL2_image.cmake
  18. 66 0
      CMake/Modules/Emscripten/Findglfw3.cmake
  19. 2 2
      CMake/Modules/FindLuaJIT.cmake
  20. 0 147
      CMake/Modules/FindPkgMacros.cmake
  21. 0 191
      CMake/Modules/FindSDL2.cmake
  22. 48 112
      CMake/Modules/FindSDL2_image.cmake
  23. 0 209
      CMake/Modules/FindSFML.cmake
  24. 64 18
      CMake/Modules/Findlunasvg.cmake
  25. 32 0
      CMake/OptionsLists.cmake
  26. 85 0
      CMake/PackageUtilities.cmake
  27. 0 190
      CMake/Platform/iOS.cmake
  28. 0 11
      CMake/RmlUiConfig.cmake.build.in
  29. 34 0
      CMake/RmlUiConfig.cmake.in
  30. 0 7
      CMake/RmlUiConfig.cmake.install.in
  31. 46 0
      CMake/RuntimeUtilities.cmake
  32. 0 234
      CMake/SampleFileList.cmake
  33. 192 0
      CMake/Utilities.cmake
  34. 0 181
      CMake/builddist.py
  35. 0 80
      CMake/gen_filelists.sh
  36. 0 34
      CMake/gen_samplelists.sh
  37. 0 22
      CMake/plist/RocketControlsOSX-Info.plist
  38. 0 22
      CMake/plist/RocketCoreOSX-Info.plist
  39. 0 22
      CMake/plist/RocketDebuggerOSX-Info.plist
  40. 152 1092
      CMakeLists.txt
  41. 58 0
      CMakePresets.json
  42. 0 0
      Dependencies/empty.txt
  43. 0 65
      Dependencies/osx-depends.sh
  44. 1 1
      Include/RmlUi/Core/Header.h
  45. 2 2
      Include/RmlUi/Core/Traits.h
  46. 1 1
      Include/RmlUi/Debugger/Header.h
  47. 1 1
      Include/RmlUi/Lua/Header.h
  48. 2 2
      Include/RmlUi/Lua/IncludeLua.h
  49. 35 0
      Samples/CMakeLists.txt
  50. 32 0
      Samples/basic/CMakeLists.txt
  51. 12 0
      Samples/basic/animation/CMakeLists.txt
  52. 12 0
      Samples/basic/benchmark/CMakeLists.txt
  53. 16 0
      Samples/basic/bitmapfont/CMakeLists.txt
  54. 14 0
      Samples/basic/customlog/CMakeLists.txt
  55. 12 0
      Samples/basic/databinding/CMakeLists.txt
  56. 12 0
      Samples/basic/demo/CMakeLists.txt
  57. 16 0
      Samples/basic/drag/CMakeLists.txt
  58. 12 0
      Samples/basic/effects/CMakeLists.txt
  59. 35 0
      Samples/basic/harfbuzz/CMakeLists.txt
  60. 0 0
      Samples/basic/harfbuzz/data/Cairo-Regular.ttf
  61. 0 0
      Samples/basic/harfbuzz/data/LICENSE.txt
  62. 0 0
      Samples/basic/harfbuzz/data/Poppins-Regular.ttf
  63. 0 0
      Samples/basic/harfbuzz/data/harfbuzz.rml
  64. 0 0
      Samples/basic/harfbuzz/src/FontEngineInterfaceHarfBuzz.cpp
  65. 0 0
      Samples/basic/harfbuzz/src/FontEngineInterfaceHarfBuzz.h
  66. 0 0
      Samples/basic/harfbuzz/src/FontFace.cpp
  67. 0 0
      Samples/basic/harfbuzz/src/FontFace.h
  68. 4 2
      Samples/basic/harfbuzz/src/FontFaceHandleHarfBuzz.cpp
  69. 0 0
      Samples/basic/harfbuzz/src/FontFaceHandleHarfBuzz.h
  70. 0 0
      Samples/basic/harfbuzz/src/FontFaceLayer.cpp
  71. 0 0
      Samples/basic/harfbuzz/src/FontFaceLayer.h
  72. 0 0
      Samples/basic/harfbuzz/src/FontFamily.cpp
  73. 0 0
      Samples/basic/harfbuzz/src/FontFamily.h
  74. 0 0
      Samples/basic/harfbuzz/src/FontGlyph.h
  75. 0 0
      Samples/basic/harfbuzz/src/FontProvider.cpp
  76. 0 0
      Samples/basic/harfbuzz/src/FontProvider.h
  77. 0 0
      Samples/basic/harfbuzz/src/FreeTypeInterface.cpp
  78. 0 0
      Samples/basic/harfbuzz/src/FreeTypeInterface.h
  79. 0 0
      Samples/basic/harfbuzz/src/LanguageData.h
  80. 5 5
      Samples/basic/harfbuzz/src/main.cpp
  81. 12 0
      Samples/basic/loaddocument/CMakeLists.txt
  82. 12 0
      Samples/basic/lottie/CMakeLists.txt
  83. 12 0
      Samples/basic/svg/CMakeLists.txt
  84. 12 0
      Samples/basic/transform/CMakeLists.txt
  85. 14 0
      Samples/basic/treeview/CMakeLists.txt
  86. 48 0
      Samples/invaders/CMakeLists.txt
  87. 42 0
      Samples/luainvaders/CMakeLists.txt
  88. 1 1
      Samples/readme.md
  89. 29 0
      Samples/shell/CMakeLists.txt
  90. 21 6
      Samples/shell/src/PlatformExtensions.cpp
  91. 4 0
      Samples/tutorial/CMakeLists.txt
  92. 14 0
      Samples/tutorial/drag/CMakeLists.txt
  93. 12 0
      Samples/tutorial/template/CMakeLists.txt
  94. 14 0
      Source/CMakeLists.txt
  95. 467 0
      Source/Core/CMakeLists.txt
  96. 6 6
      Source/Core/Core.cpp
  97. 50 0
      Source/Core/Elements/CMakeLists.txt
  98. 22 0
      Source/Core/FontEngineDefault/CMakeLists.txt
  99. 40 0
      Source/Core/Layout/CMakeLists.txt
  100. 67 0
      Source/Debugger/CMakeLists.txt

+ 12 - 111
.appveyor.yml

@@ -1,126 +1,27 @@
 version: build.{build}
 version: build.{build}
 
 
-image:
-  - Visual Studio 2017
+image: Visual Studio 2017
 
 
 environment:
 environment:
-  FREETYPE_VER: 2.10.1
-  VS_SHORTNAME: vs2017
-  matrix:
-    - VS_GENERATOR: Visual Studio 15 2017 Win64
-      PLATFORM_NAME: win64
-    - VS_GENERATOR: Visual Studio 15 2017
-      PLATFORM_NAME: win32
+  FREETYPE_VER: 2.11.1
+  VS_GENERATOR: Visual Studio 15 2017 Win64
 
 
 install:
 install:
 - cmd: |-
 - cmd: |-
     cd Dependencies
     cd Dependencies
-
-    appveyor DownloadFile https://github.com/ubawurinna/freetype-windows-binaries/releases/download/v%FREETYPE_VER%/freetype.zip
-    unzip -o freetype.zip -d freetype_tmp
-    mv freetype_tmp/include include
-    mv freetype_tmp/%PLATFORM_NAME% lib
-
-    git clone --depth 1 --branch v0.2 https://github.com/Samsung/rlottie.git
-    cd rlottie
-    mkdir build
-    cd build
-    cmake -G "%VS_GENERATOR%" -DBUILD_SHARED_LIBS=OFF -DLOTTIE_MODULE=OFF ..
-    cmake --build . --target rlottie --config Debug -- "/clp:ErrorsOnly"
-    cmake --build . --target rlottie --config Release -- "/clp:ErrorsOnly"
-    cd ../../
-
-    git clone --depth 1 --branch v2.3.1 https://github.com/sammycage/lunasvg.git
-    cd lunasvg
-    mkdir build
-    cd build
-    cmake -G "%VS_GENERATOR%" -DBUILD_SHARED_LIBS=OFF -DLUNASVG_BUILD_EXAMPLES=OFF ..
-    cmake --build . --target lunasvg --config Debug -- "/clp:ErrorsOnly"
-    cmake --build . --target lunasvg --config Release -- "/clp:ErrorsOnly"
-    cd ../../
-
+    appveyor DownloadFile https://github.com/ubawurinna/freetype-windows-binaries/archive/refs/tags/v%FREETYPE_VER%.zip
+    unzip -o v%FREETYPE_VER%.zip
+    mv "freetype-windows-binaries-%FREETYPE_VER%/include" include
+    mv "freetype-windows-binaries-%FREETYPE_VER%/release dll/win64" lib
     cd ..
     cd ..
-    mkdir Build-Dynamic, Build-Static, Build-Samples
-
-    cd Build-Dynamic
-    cmake -G "%VS_GENERATOR%" -DBUILD_SHARED_LIBS=ON -DBUILD_SAMPLES=OFF -DWARNINGS_AS_ERRORS=ON ..
-
-    cd ../Build-Static
-    cmake -G "%VS_GENERATOR%" -DBUILD_SHARED_LIBS=OFF -DBUILD_SAMPLES=OFF -DWARNINGS_AS_ERRORS=ON ..
 
 
-    cd ../Build-Samples
-    cmake -G "%VS_GENERATOR%" -DBUILD_SHARED_LIBS=ON -DENABLE_LOTTIE_PLUGIN=ON -DENABLE_SVG_PLUGIN=ON -DBUILD_SAMPLES=ON -DWARNINGS_AS_ERRORS=ON ..
-
-    cd ..
+    cmake -B Build -G "%VS_GENERATOR%" -DBUILD_SHARED_LIBS=ON -DRMLUI_WARNINGS_AS_ERRORS=ON
 
 
 build_script:
 build_script:
 - cmd: |-
 - cmd: |-
-    msbuild Build-Dynamic/RmlUi.sln /p:configuration=debug   /verbosity:minimal /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
-
-    msbuild Build-Dynamic/RmlUi.sln /p:configuration=release /verbosity:minimal /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
-
-    msbuild Build-Static/RmlUi.sln  /p:configuration=debug   /verbosity:minimal /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
-
-    msbuild Build-Static/RmlUi.sln  /p:configuration=release /verbosity:minimal /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
-
-    msbuild Build-Samples/RmlUi.sln  /p:configuration=release /verbosity:minimal /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
+    cmake --build Build --config Debug -- /verbosity:minimal /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
+    cmake --build Build --config Release -- /verbosity:minimal /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
 
 
 after_build:
 after_build:
-- cmd: |-
-    mkdir Bin
-    cd Bin
-    mkdir Dynamic-Debug, Dynamic-Release, Static-Debug, Static-Release
-    cp ../Build-Dynamic/Debug/Rml*.{lib,dll,pdb} Dynamic-Debug
-    cp ../Build-Dynamic/Release/Rml*.{lib,dll} Dynamic-Release
-    cp ../Build-Static/Debug/Rml*.{lib,pdb} Static-Debug
-    cp ../Build-Static/Release/Rml*.lib Static-Release
-    cd ..
-
-    cp Build-Samples/Release/*.exe Samples
-    cp Build-Samples/Release/Rml*.dll Samples
-    cp Dependencies/lib/*.dll Samples
-
-    mv Dependencies/lib/ Dependencies/freetype-%FREETYPE_VER%
-    cp Dependencies/freetype_tmp/*.TXT Dependencies/freetype-%FREETYPE_VER%
-
-    IF NOT "%APPVEYOR_REPO_TAG_NAME%"=="" SET RMLUI_VERSION= %APPVEYOR_REPO_TAG_NAME%
-
-    echo RmlUi%RMLUI_VERSION% library and sample binaries for %PLATFORM_NAME%.> Build.txt& echo.>>Build.txt
-    echo https://github.com/mikke89/RmlUi>> Build.txt& echo.>>Build.txt
-    echo Built using %VS_GENERATOR% on %APPVEYOR_REPO_COMMIT_TIMESTAMP:~0,10% (build %APPVEYOR_BUILD_NUMBER%).>> Build.txt
-    echo Commit id: %APPVEYOR_REPO_COMMIT%.>> Build.txt
-
-    cd Dependencies/rlottie/
-    echo The rlottie library includes source code licensed under Mozilla Public License Version 2.0.> MPL_SOURCE.txt
-    echo The source for this code can be found in the rlottie library at the following URL:>> MPL_SOURCE.txt
-    echo https://github.com/Samsung/rlottie/blob/29b391b95913877b7234543da8b4a9ec6d8175d0/src/vector/vinterpolator.cpp>> MPL_SOURCE.txt
-    cd ../..
-
-    cp Include/RmlUi/Core/Containers/LICENSE.txt LICENSE.Core.ThirdParty.txt
-    cp Source/Debugger/LICENSE.txt LICENSE.Debugger.ThirdParty.txt
-
-    7z a RmlUi-%VS_SHORTNAME%-%PLATFORM_NAME%.zip Backends/ Bin/ Include/ Samples/ Build.txt readme.md changelog.md LICENSE* Dependencies/freetype-%FREETYPE_VER%/ Dependencies/rlottie/COPYING Dependencies/rlottie/MPL_SOURCE.txt Dependencies/rlottie/licenses/ Dependencies/lunasvg/LICENSE
-
-    mkdir Samples\Dependencies\freetype-%FREETYPE_VER%, Samples\Dependencies\rlottie, Samples\Dependencies\rlottie\licenses, Samples\Dependencies\lunasvg
-    cp LICENSE* Samples
-    cp Dependencies/freetype-%FREETYPE_VER%/*.TXT Samples/Dependencies/freetype-%FREETYPE_VER%
-    cp Dependencies/rlottie/COPYING Samples/Dependencies/rlottie
-    cp Dependencies/rlottie/MPL_SOURCE.txt Samples/Dependencies/rlottie
-    cp Dependencies/rlottie/licenses/* Samples/Dependencies/rlottie/licenses
-    cp Dependencies/lunasvg/LICENSE Samples/Dependencies/lunasvg
-
-    IF "%PLATFORM_NAME%"=="win64" 7z a RmlUi-%PLATFORM_NAME%-samples-only.zip .\Samples\* -r -xr!src\ -x!shell\ -x!luainvaders\
-
-artifacts:
-- path: RmlUi-*.zip
-deploy:
-  release: RmlUi $(APPVEYOR_REPO_TAG_NAME)
-  description: 'Release description'
-  provider: GitHub
-  auth_token:
-    secure: YN5NBflQ6G3yLsNYRPTjgz5vXqaZeIstxzRx4XqC8VVOUKL/TY2JOdxNQKTZOwLM
-  artifact: /.*\.zip/
-  draft: true
-  prerelease: false
-  on:
-    APPVEYOR_REPO_TAG: true
+  - cmd: |-
+      ls Build/*/*.dll -s -h -X

+ 7 - 1
.editorconfig

@@ -1,6 +1,12 @@
 root = true
 root = true
 
 
-[CMakeLists.txt]
+[{CMakeLists.txt,*.cmake,*.cmake.in}]
+indent_style = tab
+indent_size = 4
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[CMakePresets.json]
 indent_style = tab
 indent_style = tab
 indent_size = 4
 indent_size = 4
 trim_trailing_whitespace = true
 trim_trailing_whitespace = true

+ 95 - 53
.github/workflows/build.yml

@@ -17,42 +17,37 @@ jobs:
         include:
         include:
           - cc: clang
           - cc: clang
             cxx: clang++
             cxx: clang++
-            cmake_options: -DENABLE_PRECOMPILED_HEADERS=OFF -DSAMPLES_BACKEND=GLFW_GL2
+            cmake_options: -DRMLUI_BACKEND=GLFW_GL2 -DRMLUI_PRECOMPILED_HEADERS=OFF
           - cc: clang
           - cc: clang
             cxx: clang++
             cxx: clang++
-            cmake_options: -DBUILD_TESTING=ON -DSAMPLES_BACKEND=SDL_VK -DCMAKE_BUILD_TYPE=Debug
-          - cmake_options: -DBUILD_TESTING=ON -DENABLE_PRECOMPILED_HEADERS=OFF
+            cmake_options: -DRMLUI_BACKEND=SDL_VK -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON
+          - cmake_options: -DRMLUI_BACKEND=GLFW_GL3 -DBUILD_TESTING=ON
             enable_testing: true
             enable_testing: true
-          - cmake_options: -DNO_FONT_INTERFACE_DEFAULT=ON -DENABLE_LOTTIE_PLUGIN=ON -DSAMPLES_BACKEND=X11_GL2
-          - cmake_options: -DDISABLE_RTTI_AND_EXCEPTIONS=ON -DSAMPLES_BACKEND=SDL_GL2
-          - cmake_options: -DNO_THIRDPARTY_CONTAINERS=ON -DSAMPLES_BACKEND=SFML_GL2
-          - cmake_options: -DSAMPLES_BACKEND=SDL_VK -DRMLUI_VK_DEBUG=ON -DENABLE_PRECOMPILED_HEADERS=OFF -DCMAKE_BUILD_TYPE=Debug
+          - cmake_options: -DRMLUI_BACKEND=X11_GL2 -DRMLUI_LOTTIE_PLUGIN=ON
+          - cmake_options: -DRMLUI_BACKEND=SDL_GL2 -DRMLUI_CUSTOM_RTTI=ON -DCMAKE_CXX_FLAGS="-fno-exceptions -fno-rtti"
+          - cmake_options: -DRMLUI_BACKEND=SFML_GL2 -DRMLUI_THIRDPARTY_CONTAINERS=OFF
+          - cmake_options: -DRMLUI_BACKEND=GLFW_VK -DCMAKE_BUILD_TYPE=Debug -DRMLUI_VK_DEBUG=ON -DRMLUI_PRECOMPILED_HEADERS=OFF
 
 
     steps:
     steps:
-    - uses: actions/checkout@v3
+    - uses: actions/checkout@v4
 
 
     - name: Install Dependencies
     - name: Install Dependencies
       run: |-
       run: |-
         sudo apt-get update
         sudo apt-get update
-        sudo apt-get install cmake ninja-build libsdl2-dev libsdl2-image-dev libfreetype6-dev libglew-dev liblua5.2-dev libsfml-dev librlottie-dev libglfw3-dev
-
-    - name: Create Build Environment
-      run: cmake -E make_directory ${{github.workspace}}/Build
+        sudo apt-get install cmake ninja-build libsdl2-dev libsdl2-image-dev libfreetype6-dev libharfbuzz-dev libglew-dev liblua5.2-dev libsfml-dev librlottie-dev libglfw3-dev
 
 
     - name: Configure CMake
     - name: Configure CMake
-      working-directory: ${{github.workspace}}/Build
       run: >-
       run: >-
-        cmake $GITHUB_WORKSPACE -G Ninja -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DBUILD_LUA_BINDINGS=ON -DBUILD_SAMPLES=ON -DWARNINGS_AS_ERRORS=ON
+        cmake -B Build -G Ninja --preset samples-all -DRMLUI_SVG_PLUGIN=OFF -Wdev -Werror=dev -DRMLUI_WARNINGS_AS_ERRORS=ON
         ${{ matrix.cmake_options }}
         ${{ matrix.cmake_options }}
 
 
     - name: Build
     - name: Build
-      working-directory: ${{github.workspace}}/Build
-      run: cmake --build . --config $BUILD_TYPE
+      run: cmake --build Build
 
 
     - name: Test
     - name: Test
       if: ${{ matrix.enable_testing }}
       if: ${{ matrix.enable_testing }}
       working-directory: ${{github.workspace}}/Build
       working-directory: ${{github.workspace}}/Build
-      run: ctest -C $BUILD_TYPE
+      run: ctest
 
 
 
 
   Linux-legacy:
   Linux-legacy:
@@ -69,33 +64,58 @@ jobs:
         include:
         include:
           - cc: clang
           - cc: clang
             cxx: clang++
             cxx: clang++
-            cmake_options: -DENABLE_PRECOMPILED_HEADERS=OFF -DSAMPLES_BACKEND=GLFW_GL2
+            cmake_options: -DRMLUI_BACKEND=GLFW_GL2 -DCMAKE_BUILD_TYPE=Debug
           - cc: clang
           - cc: clang
             cxx: clang++
             cxx: clang++
-            cmake_options: -DBUILD_TESTING=ON -DSAMPLES_BACKEND=SDL_VK -DCMAKE_BUILD_TYPE=Debug
+            cmake_options: -DRMLUI_BACKEND=SDL_VK -DBUILD_TESTING=ON -DRMLUI_PRECOMPILED_HEADERS=OFF
           - cmake_options: -DBUILD_TESTING=ON
           - cmake_options: -DBUILD_TESTING=ON
-          - cmake_options: -DSAMPLES_BACKEND=SDL_VK -DRMLUI_VK_DEBUG=ON -DENABLE_PRECOMPILED_HEADERS=OFF -DCMAKE_BUILD_TYPE=Debug
+          - cmake_options: -DRMLUI_BACKEND=native -DCMAKE_BUILD_TYPE=Debug -DRMLUI_VK_DEBUG=ON
 
 
     steps:
     steps:
-    - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
 
 
-    - name: Install Dependencies
-      run: |-
-        sudo apt-get update
-        sudo apt-get install cmake ninja-build libsdl2-dev libsdl2-image-dev libfreetype6-dev libglew-dev liblua5.2-dev libglfw3-dev
+      - name: Install Dependencies
+        run: |-
+          sudo apt-get update
+          sudo apt-get install cmake ninja-build libsdl2-dev libsdl2-image-dev libfreetype6-dev libharfbuzz-dev libglew-dev liblua5.2-dev libglfw3-dev
 
 
-    - name: Create Build Environment
-      run: cmake -E make_directory ${{github.workspace}}/Build
+      - name: Configure CMake
+        run: >-
+          cmake -B Build -G Ninja --preset samples-all -DRMLUI_SVG_PLUGIN=OFF -DRMLUI_LOTTIE_PLUGIN=OFF -Wdev -Werror=dev -DRMLUI_WARNINGS_AS_ERRORS=ON
+          ${{ matrix.cmake_options }}
+
+      - name: Build
+        run: cmake --build Build
+
+
+  macOS:
+    runs-on: macos-latest
+
+    env:
+      BUILD_TYPE: Release
+
+    strategy:
+      fail-fast: false
+      matrix:
+        include:
+          - cmake_options: -DRMLUI_BACKEND=auto
+          - cmake_options: -DRMLUI_BACKEND=GLFW_GL2
+
+    steps:
+    - uses: actions/checkout@v4
+
+    - name: Install Dependencies
+      run: brew install lua sdl2 sdl2_image glfw
 
 
     - name: Configure CMake
     - name: Configure CMake
-      working-directory: ${{github.workspace}}/Build
       run: >-
       run: >-
-        cmake $GITHUB_WORKSPACE -G Ninja -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DBUILD_LUA_BINDINGS=ON -DBUILD_SAMPLES=ON -DWARNINGS_AS_ERRORS=ON
+        cmake -B Build --preset samples -Wdev -Werror=dev -DRMLUI_WARNINGS_AS_ERRORS=ON
+        -DCMAKE_CXX_FLAGS="-DGL_SILENCE_DEPRECATION"
+        -DRMLUI_LUA_BINDINGS=ON
         ${{ matrix.cmake_options }}
         ${{ matrix.cmake_options }}
 
 
     - name: Build
     - name: Build
-      working-directory: ${{github.workspace}}/Build
-      run: cmake --build . --config $BUILD_TYPE
+      run: cmake --build Build
 
 
 
 
   Windows:
   Windows:
@@ -109,35 +129,59 @@ jobs:
       fail-fast: false
       fail-fast: false
       matrix:
       matrix:
         include:
         include:
-          - cmake_options: -DSAMPLES_BACKEND=auto -DENABLE_PRECOMPILED_HEADERS=OFF
-          - cmake_options: -DSAMPLES_BACKEND=Win32_VK -DRMLUI_VK_DEBUG=ON
-          - cmake_options: -DSAMPLES_BACKEND=SDL_VK -DBUILD_LUA_BINDINGS_FOR_LUAJIT=ON
+          - cmake_options: -DRMLUI_BACKEND=auto -DRMLUI_PRECOMPILED_HEADERS=OFF
+          - cmake_options: -DRMLUI_BACKEND=Win32_VK -DRMLUI_VK_DEBUG=ON
+          - cmake_options: -DRMLUI_BACKEND=SDL_VK -DRMLUI_LUA_BINDINGS_LIBRARY=luajit
 
 
     steps:
     steps:
-    - uses: actions/checkout@v3
+    - uses: actions/checkout@v4
 
 
     - name: Install Dependencies
     - name: Install Dependencies
-      run: C:\vcpkg\vcpkg install freetype[core] sdl2[core,vulkan] lua[core] luajit
-
-    - name: Create Build Environment
-      run: cmake -E make_directory ${{github.workspace}}/Build
+      run: C:\vcpkg\vcpkg install freetype[core] sdl2[core,vulkan] glfw3 lua[core] luajit
 
 
     - name: Configure CMake
     - name: Configure CMake
-      working-directory: ${{github.workspace}}/Build
       run: >-
       run: >-
-        cmake $env:GITHUB_WORKSPACE -A x64 -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=$env:BUILD_TYPE -DBUILD_LUA_BINDINGS=ON -DBUILD_SAMPLES=ON -DWARNINGS_AS_ERRORS=ON
-        -DCMAKE_TOOLCHAIN_FILE="C:/vcpkg/scripts/buildsystems/vcpkg.cmake"
-        ${{ matrix.cmake_options }}
+        cmake -B Build --preset samples -Wdev -Werror=dev -DBUILD_SHARED_LIBS=ON
+        -DRMLUI_LUA_BINDINGS=ON -DRMLUI_WARNINGS_AS_ERRORS=ON
+        -DCMAKE_TOOLCHAIN_FILE="C:/vcpkg/scripts/buildsystems/vcpkg.cmake" ${{ matrix.cmake_options }}
 
 
     - name: Build
     - name: Build
-      working-directory: ${{github.workspace}}/Build
-      run: cmake --build . --config $env:BUILD_TYPE
+      run: cmake --build Build --config $env:BUILD_TYPE
+
+
+  MinGW64:
+    runs-on: windows-latest
+
+    env:
+      CHERE_INVOKING: yes
+      MSYSTEM: MINGW64
+
+    steps:
+      - uses: actions/checkout@v4
+
+      - name: Install Dependencies
+        run: |-
+          C:\msys64\usr\bin\bash -lc ("pacman --needed --noconfirm --sync " +
+            "mingw-w64-x86_64-gcc mingw-w64-x86_64-cmake mingw-w64-x86_64-freetype mingw-w64-x86_64-lua " +
+            "mingw-w64-x86_64-SDL2 mingw-w64-x86_64-SDL2_image mingw-w64-x86_64-glew")
+
+      - name: Configure CMake
+        run: |-
+          C:\msys64\usr\bin\bash -lc ("cmake -B Build --preset samples -Wdev -Werror=dev -DCMAKE_BUILD_TYPE=Release " +
+            "-DBUILD_SHARED_LIBS=ON -DRMLUI_PRECOMPILED_HEADERS=OFF -DRMLUI_WARNINGS_AS_ERRORS=ON " +
+            "-DRMLUI_BACKEND=SDL_GL3 -DRMLUI_LUA_BINDINGS=ON")
+
+      - name: Build
+        run: C:\msys64\usr\bin\bash -lc "cmake --build Build"
+
+      - name: List files
+        run: C:\msys64\usr\bin\bash -lc "ls Build/*.{exe,dll} -s -h -X"
 
 
 
 
   Emscripten:
   Emscripten:
-    runs-on: ubuntu-20.04
+    runs-on: ubuntu-latest
     steps:
     steps:
-    - uses: actions/checkout@v3
+    - uses: actions/checkout@v4
 
 
     - name: Install Dependencies
     - name: Install Dependencies
       run: |-
       run: |-
@@ -149,17 +193,15 @@ jobs:
         emsdk-master/emsdk install latest
         emsdk-master/emsdk install latest
         emsdk-master/emsdk activate latest
         emsdk-master/emsdk activate latest
 
 
-    - name: Create Build Environment
-      run: cmake -E make_directory Build
-
     - name: Configure CMake
     - name: Configure CMake
       run: |-
       run: |-
         source emsdk-master/emsdk_env.sh
         source emsdk-master/emsdk_env.sh
-        cd Build
-        emcmake cmake $GITHUB_WORKSPACE -DBUILD_SAMPLES=ON -DBUILD_SHARED_LIBS=OFF -DWARNINGS_AS_ERRORS=ON -DEMSCRIPTEN_EXE_FLAGS="-O1"
+        emcmake cmake -B Build --preset samples -Wdev -Werror=dev -DCMAKE_BUILD_TYPE=Release \
+        -DBUILD_SHARED_LIBS=OFF -DRMLUI_WARNINGS_AS_ERRORS=ON \
+        -DCMAKE_MODULE_PATH=$GITHUB_WORKSPACE/CMake/Modules/Emscripten
 
 
     - name: Build
     - name: Build
       run: |-
       run: |-
         source emsdk-master/emsdk_env.sh
         source emsdk-master/emsdk_env.sh
         cd Build
         cd Build
-        emmake make -j4
+        emmake make -j

+ 208 - 0
.github/workflows/package.yml

@@ -0,0 +1,208 @@
+name: Package
+
+on: [push, pull_request]
+
+jobs:
+  Build:
+    runs-on: windows-2019
+
+    strategy:
+      fail-fast: false
+      matrix:
+        architecture: [win32, win64]
+        library_linkage: [Dynamic, Static]
+        build_type: [Debug, Release]
+
+    env:
+      GENERATOR: Visual Studio 16 2019
+      VCPKG_DEFAULT_TRIPLET: ${{ matrix.architecture == 'win32' && 'x86' || 'x64' }}-${{ matrix.library_linkage == 'Dynamic' && 'windows' || 'windows-static-md' }}
+
+    steps:
+      - uses: actions/checkout@v4
+
+      - name: Install Dependencies
+        run: |-
+          echo "Using vcpkg triplet: $env:VCPKG_DEFAULT_TRIPLET"
+          C:\vcpkg\vcpkg install freetype[core]
+
+      - name: Configure CMake
+        run: >-
+          cmake -B Build
+          -G "$env:GENERATOR"
+          -A ${{ matrix.architecture == 'win32' && 'Win32' || 'x64'  }}
+          -DRMLUI_WARNINGS_AS_ERRORS=ON
+          -DBUILD_SHARED_LIBS=${{ matrix.library_linkage == 'Dynamic' && 'ON' || 'OFF' }}
+          -DVCPKG_TARGET_TRIPLET="$env:VCPKG_DEFAULT_TRIPLET"
+          -DCMAKE_TOOLCHAIN_FILE="C:/vcpkg/scripts/buildsystems/vcpkg.cmake"
+          -DCMAKE_INSTALL_PREFIX="${{github.workspace}}/Install"
+          -DRMLUI_INSTALL_TARGETS_DIR=Bin-${{matrix.library_linkage}}/CMake
+          -DCMAKE_INSTALL_BINDIR=Bin-${{matrix.library_linkage}}/${{matrix.build_type}}
+          -DCMAKE_INSTALL_LIBDIR=Bin-${{matrix.library_linkage}}/${{matrix.build_type}}
+          -DCMAKE_INSTALL_INCLUDEDIR=Include
+          -DCMAKE_INSTALL_DATADIR="."
+          -DRMLUI_INSTALL_RUNTIME_DEPENDENCIES=OFF
+          -DRMLUI_INSTALL_LICENSES_AND_BUILD_INFO=ON
+          -DRMLUI_INSTALL_DEPENDENCIES_DIR="Dependencies/Bin-${{matrix.library_linkage}}"
+          -DRMLUI_ARCHITECTURE="${{ matrix.architecture }}"
+          -DRMLUI_COMMIT_DATE="$(git show $env:GITHUB_SHA --no-patch --format=%cd --date=iso)"
+          -DRMLUI_RUN_ID="$env:GITHUB_RUN_ID"
+          -DRMLUI_SHA="$env:GITHUB_SHA"
+
+      - name: Build
+        run: cmake --build Build --config ${{ matrix.build_type }}
+
+      - name: Install
+        run: cmake --install Build --config ${{ matrix.build_type }}
+
+      - name: Upload artifacts
+        uses: actions/upload-artifact@v4
+        with:
+          name: build-${{ matrix.architecture }}-${{ matrix.library_linkage }}-${{ matrix.build_type }}
+          path: ${{github.workspace}}/Install/
+          if-no-files-found: error
+
+  Samples:
+    runs-on: windows-2019
+
+    strategy:
+      fail-fast: false
+      matrix:
+        architecture: [win32, win64]
+
+    env:
+      GENERATOR: Visual Studio 16 2019
+      VCPKG_DEFAULT_TRIPLET: ${{ matrix.architecture == 'win32' && 'x86' || 'x64' }}-windows${{ matrix.architecture == 'win64' && '-release' || '' }}
+
+    steps:
+      - uses: actions/checkout@v4
+
+      - uses: actions/checkout@v4
+        name: Checkout dependency rlottie
+        with:
+          repository: 'Samsung/rlottie'
+          ref: 'd40008707addacb636ff435236d31c694ce2b6cf'
+          path: 'Dependencies/rlottie'
+
+      - name: Install Dependencies
+        run: |-
+          echo "Using vcpkg triplet: $env:VCPKG_DEFAULT_TRIPLET"
+          C:\vcpkg\vcpkg install glfw3[core] freetype[core] lua[core] lunasvg[core]
+          cd Dependencies\rlottie
+          cmake -B build -G "$env:GENERATOR" -A ${{ matrix.architecture == 'win32' && 'Win32' || 'x64' }} -DBUILD_SHARED_LIBS=ON -DLOTTIE_MODULE=OFF
+          cmake --build build --target rlottie --config Release -- "/clp:ErrorsOnly"
+
+      - name: Configure CMake
+        run: >-
+          cmake -B Build
+          -G "$env:GENERATOR"
+          -A ${{ matrix.architecture == 'win32' && 'Win32' || 'x64' }}
+          --preset samples-all
+          -DRMLUI_HARFBUZZ_SAMPLE=OFF
+          -DRMLUI_BACKEND=GLFW_GL3
+          -DBUILD_SHARED_LIBS=ON
+          -DRMLUI_WARNINGS_AS_ERRORS=ON
+          -DVCPKG_TARGET_TRIPLET="$env:VCPKG_DEFAULT_TRIPLET"
+          -DCMAKE_TOOLCHAIN_FILE="C:/vcpkg/scripts/buildsystems/vcpkg.cmake"
+          -DCMAKE_INSTALL_PREFIX="${{github.workspace}}/Install"
+          -DCMAKE_INSTALL_BINDIR="Samples"
+          -DCMAKE_INSTALL_DATADIR="."
+          -DRMLUI_INSTALL_LICENSES_AND_BUILD_INFO=ON
+          -DRMLUI_ARCHITECTURE="${{ matrix.architecture }}"
+          -DRMLUI_COMMIT_DATE="$(git show $env:GITHUB_SHA --no-patch --format=%cd --date=iso)"
+          -DRMLUI_RUN_ID="$env:GITHUB_RUN_ID"
+          -DRMLUI_SHA="$env:GITHUB_SHA"
+
+      - name: Build
+        run: cmake --build Build --config Release
+
+      - name: Copy runtime dependencies
+        run: cp Dependencies/rlottie/build/Release/rlottie.dll Build/Release/
+
+      - name: Install
+        run: cmake --install Build --config Release
+
+      - name: Copy readme
+        run: |-
+          cp readme.md Install/
+          cp changelog.md Install/
+          cp Samples/readme.md Install/Samples/
+
+      - name: Copy extra license files
+        run: |-
+          cp Dependencies/rlottie/licenses Install/Dependencies/rlottie -Recurse
+          cp Dependencies/rlottie/COPYING Install/Dependencies/rlottie
+          echo @'
+          The rlottie library includes source code licensed under Mozilla Public License Version 2.0.
+          The source for this code can be found in the rlottie library at the following URL:
+          https://github.com/Samsung/rlottie/blob/d40008707addacb636ff435236d31c694ce2b6cf/src/vector/vinterpolator.cpp
+          '@ > "Install/Dependencies/rlottie/vinterpolator.txt"
+
+      - uses: actions/upload-artifact@v4
+        with:
+          name: samples-${{ matrix.architecture }}
+          path: |
+            ${{github.workspace}}/Install/
+            !${{github.workspace}}/Install/lib/
+            !${{github.workspace}}/Install/include/
+          if-no-files-found: error
+
+  Package:
+    needs: [Build, Samples]
+    runs-on: windows-2019
+
+    strategy:
+      fail-fast: true
+      matrix:
+        architecture: [win32, win64]
+
+    steps:
+      # Download artifacts in a well-defined order, with release binaries last.
+      - uses: actions/download-artifact@v4
+        with:
+          name: samples-${{ matrix.architecture }}
+
+      - uses: actions/download-artifact@v4
+        with:
+          name: build-${{ matrix.architecture }}-Dynamic-Debug
+
+      - uses: actions/download-artifact@v4
+        with:
+          name: build-${{ matrix.architecture }}-Static-Debug
+
+      - uses: actions/download-artifact@v4
+        with:
+          name: build-${{ matrix.architecture }}-Dynamic-Release
+
+      - uses: actions/download-artifact@v4
+        with:
+          name: build-${{ matrix.architecture }}-Static-Release
+
+      - uses: actions/upload-artifact@v4
+        with:
+          name: RmlUi-vs2019-${{ matrix.architecture }}
+          path: ./
+
+  Release:
+    needs: [Package]
+    runs-on: windows-2019
+    if: ${{ github.ref_type == 'tag' }}
+    permissions:
+      contents: write
+    steps:
+      - name: Download release artifacts
+        run: |
+          $release_artifacts = "RmlUi-vs2019-win64", "RmlUi-vs2019-win32", "samples-win64"
+          $headers = @{ "Authorization" = "token ${{ secrets.GITHUB_TOKEN }}" }
+          $response = Invoke-RestMethod -Uri "https://api.github.com/repos/$env:GITHUB_REPOSITORY/actions/runs/$env:GITHUB_RUN_ID/artifacts" -Headers $headers
+          foreach ($name in $release_artifacts) {
+            $artifact = $response.artifacts | Where-Object { $_.name -eq $name }
+            Invoke-WebRequest -Uri $artifact.archive_download_url -OutFile "$name.zip" -Headers $headers
+          }
+
+      - name: Release
+        uses: softprops/action-gh-release@v2
+        with:
+          name: RmlUi ${{ github.ref_name }}
+          files: "*.zip"
+          draft: true
+          fail_on_unmatched_files: true

+ 8 - 0
.gitignore

@@ -1,6 +1,9 @@
 # Primary CMake build target
 # Primary CMake build target
 /Build/
 /Build/
 
 
+# Primary CMake install target for development
+/Install/
+
 # Other common build targets
 # Other common build targets
 /build*/
 /build*/
 /Build*/
 /Build*/
@@ -9,6 +12,8 @@
 /Lib/
 /Lib/
 /lib/
 /lib/
 /out/
 /out/
+/Install*/
+/install*/
 
 
 # Distribution target
 # Distribution target
 /Distribution/
 /Distribution/
@@ -22,6 +27,9 @@
 # Not ignore .github/
 # Not ignore .github/
 !.github/
 !.github/
 
 
+# CMake user files
+CMakeUserPresets.json
+
 # Visual Studio project files
 # Visual Studio project files
 *.suo
 *.suo
 *.user
 *.user

+ 191 - 0
Backends/CMakeLists.txt

@@ -0,0 +1,191 @@
+#[[
+	Interface libraries for each backend, including their source files and linking requirements.
+
+	Every time a new backend gets added or its target name is modified, please update
+	the list of available backends found in OptionsLists.cmake
+]]
+
+add_library(rmlui_backend_common_headers INTERFACE)
+target_include_directories(rmlui_backend_common_headers INTERFACE "${CMAKE_CURRENT_LIST_DIR}")
+target_sources(rmlui_backend_common_headers INTERFACE
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Backend.h"
+)
+
+add_library(rmlui_backend_Win32_GL2 INTERFACE)
+target_sources(rmlui_backend_Win32_GL2 INTERFACE
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Platform_Win32.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Renderer_GL2.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Backend_Win32_GL2.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Platform_Win32.h"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Renderer_GL2.h"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Include_Windows.h"
+)
+target_link_libraries(rmlui_backend_Win32_GL2 INTERFACE rmlui_backend_common_headers OpenGL::GL)
+
+add_library(rmlui_backend_Win32_VK INTERFACE)
+target_sources(rmlui_backend_Win32_VK INTERFACE
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Platform_Win32.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Renderer_VK.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Backend_Win32_VK.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Platform_Win32.h"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Renderer_VK.h"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Include_Vulkan.h"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Vulkan/ShadersCompiledSPV.h"
+)
+target_link_libraries(rmlui_backend_Win32_VK INTERFACE rmlui_backend_common_headers)
+
+add_library(rmlui_backend_X11_GL2 INTERFACE)
+target_sources(rmlui_backend_X11_GL2 INTERFACE
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Platform_X11.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Renderer_GL2.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Backend_X11_GL2.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Platform_X11.h"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Renderer_GL2.h"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Include_Xlib.h"
+)
+
+# RMLUI_CMAKE_MINIMUM_VERSION_RAISE_NOTICE:
+# Once the minimum CMake version is CMake >= 3.14, "${X11_LIBRARIES}" should
+# be substituted by "X11:X11" in addition to any of the other imported that might
+# be required. More info:
+# https://cmake.org/cmake/help/latest/module/FindX11.html
+target_link_libraries(rmlui_backend_X11_GL2 INTERFACE rmlui_backend_common_headers OpenGL::GL ${X11_LIBRARIES})
+
+add_library(rmlui_backend_SDL_GL2 INTERFACE)
+target_sources(rmlui_backend_SDL_GL2 INTERFACE
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Platform_SDL.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Renderer_GL2.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Backend_SDL_GL2.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Platform_SDL.h"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Renderer_GL2.h"
+)
+target_link_libraries(rmlui_backend_SDL_GL2 INTERFACE rmlui_backend_common_headers OpenGL::GL SDL2::SDL2 GLEW::GLEW SDL2_image::SDL2_image)
+
+add_library(rmlui_backend_SDL_GL3 INTERFACE)
+target_sources(rmlui_backend_SDL_GL3 INTERFACE
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Platform_SDL.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Renderer_GL3.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Backend_SDL_GL3.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Platform_SDL.h"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Renderer_GL3.h"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Include_GL3.h"
+)
+target_link_libraries(rmlui_backend_SDL_GL3 INTERFACE rmlui_backend_common_headers OpenGL::GL SDL2::SDL2 SDL2_image::SDL2_image)
+if(UNIX)
+	# The OpenGL 3 renderer implementation uses dlopen/dlclose
+	# This is required in some UNIX and UNIX-like operating systems to load shared object files at runtime
+	target_link_libraries(rmlui_backend_SDL_GL3 INTERFACE ${CMAKE_DL_LIBS})
+endif()
+
+add_library(rmlui_backend_SDL_VK INTERFACE)
+target_sources(rmlui_backend_SDL_VK INTERFACE
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Platform_SDL.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Renderer_VK.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Backend_SDL_VK.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Platform_SDL.h"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Renderer_VK.h"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Include_Vulkan.h"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Vulkan/ShadersCompiledSPV.h"
+)
+target_link_libraries(rmlui_backend_SDL_VK INTERFACE rmlui_backend_common_headers SDL2::SDL2)
+if(UNIX)
+	# The Vulkan renderer implementation uses dlopen/dlclose
+	# This is required in some UNIX and UNIX-like operating systems to load shared object files at runtime
+	target_link_libraries(rmlui_backend_SDL_VK INTERFACE ${CMAKE_DL_LIBS})
+endif()
+
+add_library(rmlui_backend_SDL_SDLrenderer INTERFACE)
+target_sources(rmlui_backend_SDL_SDLrenderer INTERFACE
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Renderer_SDL.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Platform_SDL.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Backend_SDL_SDLrenderer.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Platform_SDL.h"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Renderer_SDL.h"
+)
+target_link_libraries(rmlui_backend_SDL_SDLrenderer INTERFACE rmlui_backend_common_headers SDL2::SDL2 SDL2_image::SDL2_image)
+
+add_library(rmlui_backend_SFML_GL2 INTERFACE)
+target_sources(rmlui_backend_SFML_GL2 INTERFACE
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Platform_SFML.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Renderer_GL2.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Backend_SFML_GL2.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Platform_SFML.h"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Renderer_GL2.h"
+)
+target_link_libraries(rmlui_backend_SFML_GL2 INTERFACE
+	rmlui_backend_common_headers OpenGL::GL SFML::Graphics SFML::Window SFML::System
+)
+
+add_library(rmlui_backend_GLFW_GL2 INTERFACE)
+target_sources(rmlui_backend_GLFW_GL2 INTERFACE
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Platform_GLFW.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Renderer_GL2.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Backend_GLFW_GL2.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Platform_GLFW.h"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Renderer_GL2.h"
+)
+target_link_libraries(rmlui_backend_GLFW_GL2 INTERFACE rmlui_backend_common_headers OpenGL::GL glfw)
+
+add_library(rmlui_backend_GLFW_GL3 INTERFACE)
+target_sources(rmlui_backend_GLFW_GL3 INTERFACE
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Platform_GLFW.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Renderer_GL3.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Backend_GLFW_GL3.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Platform_GLFW.h"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Renderer_GL3.h"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Include_GL3.h"
+)
+target_link_libraries(rmlui_backend_GLFW_GL3 INTERFACE rmlui_backend_common_headers OpenGL::GL glfw)
+if(UNIX)
+	# The OpenGL 3 renderer implementation uses dlopen/dlclose
+	# This is required in some UNIX and UNIX-like operating systems to load shared object files at runtime
+	target_link_libraries(rmlui_backend_GLFW_GL3 INTERFACE ${CMAKE_DL_LIBS})
+endif()
+
+add_library(rmlui_backend_GLFW_VK INTERFACE)
+target_sources(rmlui_backend_GLFW_VK INTERFACE
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Platform_GLFW.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Renderer_VK.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Backend_GLFW_VK.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Platform_GLFW.h"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Renderer_VK.h"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Include_Vulkan.h"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Vulkan/ShadersCompiledSPV.h"
+)
+target_link_libraries(rmlui_backend_GLFW_VK INTERFACE rmlui_backend_common_headers glfw)
+if(UNIX)
+	# The Vulkan renderer implementation uses dlopen/dlclose
+	# This is required in some UNIX and UNIX-like operating systems to load shared object files at runtime
+	target_link_libraries(rmlui_backend_GLFW_VK INTERFACE ${CMAKE_DL_LIBS})
+endif()
+
+add_library(rmlui_backend_BackwardCompatible_GLFW_GL2 INTERFACE)
+target_sources(rmlui_backend_BackwardCompatible_GLFW_GL2 INTERFACE
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Platform_GLFW.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Platform_GLFW.h"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_BackwardCompatible/RmlUi_Renderer_BackwardCompatible_GL2.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_BackwardCompatible/RmlUi_Renderer_BackwardCompatible_GL2.h"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_BackwardCompatible/RmlUi_Backend_BackwardCompatible_GLFW_GL2.cpp"
+)
+target_link_libraries(rmlui_backend_BackwardCompatible_GLFW_GL2 INTERFACE rmlui_backend_common_headers OpenGL::GL glfw)
+
+add_library(rmlui_backend_BackwardCompatible_GLFW_GL3 INTERFACE)
+target_sources(rmlui_backend_BackwardCompatible_GLFW_GL3 INTERFACE
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Platform_GLFW.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_Platform_GLFW.h"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_BackwardCompatible/RmlUi_Renderer_BackwardCompatible_GL3.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_BackwardCompatible/RmlUi_Renderer_BackwardCompatible_GL3.h"
+	"${CMAKE_CURRENT_LIST_DIR}/RmlUi_BackwardCompatible/RmlUi_Backend_BackwardCompatible_GLFW_GL3.cpp"
+)
+target_link_libraries(rmlui_backend_BackwardCompatible_GLFW_GL3 INTERFACE rmlui_backend_common_headers OpenGL::GL glfw)
+if(UNIX)
+	# The OpenGL 3 renderer implementation uses dlopen/dlclose
+	# This is required in some UNIX and UNIX-like operating systems to load shared object files at runtime
+	target_link_libraries(rmlui_backend_BackwardCompatible_GLFW_GL3 INTERFACE ${CMAKE_DL_LIBS})
+endif()
+
+if(RMLUI_IS_ROOT_PROJECT)
+	install(DIRECTORY "./"
+		DESTINATION "${CMAKE_INSTALL_DATADIR}/Backends"
+	)
+endif()

+ 33 - 0
CMake/BackendAutoSelection.cmake

@@ -0,0 +1,33 @@
+function(backends_auto_selection_error)
+	message(FATAL_ERROR
+		"RmlUi ${RMLUI_BACKEND} backend for ${CMAKE_SYSTEM_NAME} is not available. "
+		"Please select a backend that is available on the system. "
+		"Possible options for RMLUI_BACKEND are: ${RMLUI_BACKEND_OPTIONS}"
+	)
+endfunction()
+
+if(RMLUI_BACKEND STREQUAL "auto")
+	if(EMSCRIPTEN)
+		set(RMLUI_BACKEND SDL_GL3)
+	elseif(WIN32)
+		set(RMLUI_BACKEND GLFW_GL3)
+	elseif(APPLE)
+		set(RMLUI_BACKEND SDL_SDLrenderer)
+	elseif(UNIX)
+		set(RMLUI_BACKEND GLFW_GL3)
+	else()
+		backends_auto_selection_error()
+	endif()
+elseif(RMLUI_BACKEND STREQUAL "native")
+	if(EMSCRIPTEN)
+		set(RMLUI_BACKEND SDL_GL3)
+	elseif(WIN32)
+		set(RMLUI_BACKEND WIN32_GL2)
+	elseif(UNIX AND NOT APPLE)
+		set(RMLUI_BACKEND X11_GL2)
+	else()
+		backends_auto_selection_error()
+	endif()
+endif()
+
+message(STATUS "Using RmlUi backend ${RMLUI_BACKEND} for samples")

+ 0 - 142
CMake/BackendFileList.cmake

@@ -1,142 +0,0 @@
-set(BACKEND_COMMON_HDR_FILES
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Backend.h
-)
-
-set(Win32_GL2_SRC_FILES
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Platform_Win32.cpp
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Renderer_GL2.cpp
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Backend_Win32_GL2.cpp
-)
-set(Win32_GL2_HDR_FILES
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Platform_Win32.h
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Renderer_GL2.h
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Include_Windows.h
-)
-
-set(Win32_VK_SRC_FILES
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Platform_Win32.cpp
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Renderer_VK.cpp
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Backend_Win32_VK.cpp
-)
-set(Win32_VK_HDR_FILES
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Platform_Win32.h
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Renderer_VK.h
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Vulkan/ShadersCompiledSPV.h
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Vulkan/vk_mem_alloc.h
-)
-
-set(X11_GL2_SRC_FILES
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Platform_X11.cpp
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Renderer_GL2.cpp
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Backend_X11_GL2.cpp
-)
-set(X11_GL2_HDR_FILES
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Platform_X11.h
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Renderer_GL2.h
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Include_Xlib.h
-)
-
-set(SDL_GL2_SRC_FILES
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Platform_SDL.cpp
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Renderer_GL2.cpp
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Backend_SDL_GL2.cpp
-)
-set(SDL_GL2_HDR_FILES
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Platform_SDL.h
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Renderer_GL2.h
-)
-
-set(SDL_GL3_SRC_FILES
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Platform_SDL.cpp
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Renderer_GL3.cpp
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Backend_SDL_GL3.cpp
-)
-set(SDL_GL3_HDR_FILES
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Platform_SDL.h
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Renderer_GL3.h
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Include_GL3.h
-)
-
-set(SDL_VK_SRC_FILES
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Platform_SDL.cpp
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Renderer_VK.cpp
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Backend_SDL_VK.cpp
-)
-set(SDL_VK_HDR_FILES
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Platform_SDL.h
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Renderer_VK.h
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Vulkan/ShadersCompiledSPV.h
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Vulkan/vk_mem_alloc.h
-)
-
-set(SDL_SDLrenderer_SRC_FILES
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Renderer_SDL.cpp
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Platform_SDL.cpp
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Backend_SDL_SDLrenderer.cpp
-)
-set(SDL_SDLrenderer_HDR_FILES
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Platform_SDL.h
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Renderer_SDL.h
-)
-
-set(SFML_GL2_SRC_FILES
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Platform_SFML.cpp
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Renderer_GL2.cpp
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Backend_SFML_GL2.cpp
-)
-set(SFML_GL2_HDR_FILES
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Platform_SFML.h
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Renderer_GL2.h
-)
-
-set(GLFW_GL2_SRC_FILES
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Platform_GLFW.cpp
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Renderer_GL2.cpp
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Backend_GLFW_GL2.cpp
-)
-set(GLFW_GL2_HDR_FILES
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Platform_GLFW.h
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Renderer_GL2.h
-)
-
-set(GLFW_GL3_SRC_FILES
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Platform_GLFW.cpp
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Renderer_GL3.cpp
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Backend_GLFW_GL3.cpp
-)
-set(GLFW_GL3_HDR_FILES
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Platform_GLFW.h
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Renderer_GL3.h
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Include_GL3.h
-)
-
-set(GLFW_VK_SRC_FILES
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Platform_GLFW.cpp
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Renderer_VK.cpp
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Backend_GLFW_VK.cpp
-)
-set(GLFW_VK_HDR_FILES
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Platform_GLFW.h
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Renderer_VK.h
-)
-
-set(BackwardCompatible_GLFW_GL2_SRC_FILES
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Platform_GLFW.cpp
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_BackwardCompatible/RmlUi_Renderer_BackwardCompatible_GL2.cpp
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_BackwardCompatible/RmlUi_Backend_BackwardCompatible_GLFW_GL2.cpp
-)
-set(BackwardCompatible_GLFW_GL2_HDR_FILES
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Platform_GLFW.h
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_BackwardCompatible/RmlUi_Renderer_BackwardCompatible_GL2.h
-)
-
-set(BackwardCompatible_GLFW_GL3_SRC_FILES
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Platform_GLFW.cpp
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_BackwardCompatible/RmlUi_Renderer_BackwardCompatible_GL3.cpp
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_BackwardCompatible/RmlUi_Backend_BackwardCompatible_GLFW_GL3.cpp
-)
-set(BackwardCompatible_GLFW_GL3_HDR_FILES
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Platform_GLFW.h
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_BackwardCompatible/RmlUi_Renderer_BackwardCompatible_GL3.h
-	${PROJECT_SOURCE_DIR}/Backends/RmlUi_Include_GL3.h
-)

+ 107 - 0
CMake/Dependencies.cmake

@@ -0,0 +1,107 @@
+#[[
+	Set up external dependencies required to build RmlUi itself.
+
+	Packages are configured as soft dependencies (i.e. not REQUIRED), so that a consuming project can declare them
+	by other means, without an error being emitted here. For the same reason, instead of relying on variables like
+	*_NOTFOUND variables, we check directly for the existence of the target.
+]]
+
+if(RMLUI_FONT_ENGINE STREQUAL "freetype")
+	find_package("Freetype")
+
+	if(FREETYPE_VERSION_STRING)
+		if(FREETYPE_VERSION_STRING VERSION_EQUAL "2.11.0" AND CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
+			message(WARNING "Using Freetype 2.11.0 with MSVC can cause issues, please upgrade to Freetype 2.11.1 or newer.")
+		endif()
+	endif()
+
+	report_dependency_found_or_error("Freetype" Freetype::Freetype "Freetype font engine enabled")
+endif()
+
+if(RMLUI_LOTTIE_PLUGIN)
+	find_package("rlottie")
+	report_dependency_found_or_error("rlottie" rlottie::rlottie "Lottie plugin enabled")
+endif()
+
+if(RMLUI_SVG_PLUGIN)
+	find_package("lunasvg")
+	report_dependency_found_or_error("lunasvg" lunasvg::lunasvg "SVG plugin enabled")
+endif()
+
+# The Lua and LuaJIT modules don't provide targets, so make our own, or let users define the target already.
+if(RMLUI_LUA_BINDINGS AND (RMLUI_LUA_BINDINGS_LIBRARY STREQUAL "lua" OR RMLUI_LUA_BINDINGS_LIBRARY STREQUAL "lua_as_cxx"))
+	if(NOT TARGET Lua::Lua)
+		find_package("Lua" REQUIRED)
+		add_library(Lua::Lua INTERFACE IMPORTED)
+		set_target_properties(Lua::Lua PROPERTIES
+			INTERFACE_LINK_LIBRARIES "${LUA_LIBRARIES}"
+			INTERFACE_INCLUDE_DIRECTORIES "${LUA_INCLUDE_DIR}"
+		)
+	endif()
+	add_library(RmlUi::External::Lua ALIAS Lua::Lua)
+	set(friendly_message "Lua bindings enabled")
+	if(RMLUI_LUA_BINDINGS_LIBRARY STREQUAL "lua_as_cxx")
+		string(APPEND friendly_message " with Lua compiled as C++")
+	endif()
+	report_dependency_found_or_error("Lua" Lua::Lua "${friendly_message}")
+	unset(friendly_message)
+endif()
+
+if(RMLUI_LUA_BINDINGS AND RMLUI_LUA_BINDINGS_LIBRARY STREQUAL "luajit")
+	if(NOT TARGET LuaJIT::LuaJIT)
+		find_package("LuaJIT" REQUIRED)
+		add_library(LuaJIT::LuaJIT INTERFACE IMPORTED)
+		set_target_properties(LuaJIT::LuaJIT PROPERTIES
+			INTERFACE_LINK_LIBRARIES "${LUAJIT_LIBRARY}"
+			INTERFACE_INCLUDE_DIRECTORIES "${LUAJIT_INCLUDE_DIR}"
+		)
+	endif()
+	add_library(RmlUi::External::Lua ALIAS LuaJIT::LuaJIT)
+	report_dependency_found_or_error("Lua" LuaJIT::LuaJIT "Lua bindings enabled with LuaJIT")
+endif()
+
+if(NOT RMLUI_IS_CONFIG_FILE)
+	if(RMLUI_TRACY_PROFILING AND RMLUI_TRACY_CONFIGURATION)
+		enable_configuration_type(Tracy Release ON)
+	else()
+		enable_configuration_type(Tracy Release OFF)
+	endif()
+endif()
+
+if(RMLUI_HARFBUZZ_SAMPLE)
+	if(NOT RMLUI_FONT_ENGINE STREQUAL "freetype")
+		message(FATAL_ERROR "The HarfBuzz sample requires the default (FreeType) font engine to be enabled. Please set RMLUI_FONT_ENGINE accordingly or disable RMLUI_HARFBUZZ_SAMPLE.")
+	endif()
+
+	find_package("HarfBuzz")
+	report_dependency_found_or_error("HarfBuzz" harfbuzz::harfbuzz "HarfBuzz library available for samples")
+endif()
+
+if(RMLUI_TRACY_PROFILING)
+	find_package(Tracy CONFIG QUIET)
+
+	if(RMLUI_IS_CONFIG_FILE)
+		report_dependency_found_or_error("Tracy" Tracy::TracyClient)
+	endif()
+
+	if(NOT TARGET Tracy::TracyClient)
+		message(STATUS "Trying to add Tracy from subdirectory 'Dependencies/tracy'.")
+		add_subdirectory("Dependencies/tracy")
+
+		if(NOT TARGET Tracy::TracyClient)
+			message(FATAL_ERROR "Tracy client not found. Either "
+				"(a) make sure target Tracy::TracyClient is available from parent project, "
+				"(b) Tracy can be found as a config package, or "
+				"(c) Tracy source files are located in 'Dependencies/Tracy'.")
+		endif()
+
+		if(RMLUI_IS_ROOT_PROJECT)
+			# Tracy does not export its targets to the build tree. Do that for it here, otherwise CMake will emit an
+			# error about target `TracyClient` not being located in any export set.
+			export(EXPORT TracyConfig
+				NAMESPACE Tracy::
+				FILE TracyTargets.cmake
+			)
+		endif()
+	endif()
+endif()

+ 169 - 0
CMake/DependenciesForBackends.cmake

@@ -0,0 +1,169 @@
+#[[
+	Set up external dependencies required by the built-in backends.
+
+	All dependencies are searched as soft dependencies so that they won't error out if the library is declared by other
+	means. This file is not meant to be used by consumers of the library, only by the RmlUi CMake project.
+]]
+
+# --- Window/input APIs ---
+# SDL
+if(RMLUI_BACKEND MATCHES "^SDL")
+	# Although the official CMake find module is called FindSDL.cmake, the official config module provided by the SDL
+	# package for its version 2 is called SDL2Config.cmake. Following this trend, the official SDL config files change
+	# their name according to their major version number
+	find_package("SDL2")
+
+	#[[
+		Current code operates using a hybrid mode by detecting either the variable or the target due to the possibility
+		of package managers such as Conan and vcpkg of setting up SDL in their own way but always following the target
+		naming conventions of the official SDL config files.
+	]]
+
+	if(NOT TARGET SDL2::SDL2 AND NOT SDL2_FOUND)
+		report_dependency_not_found("SDL2" SDL2::SDL2)
+	endif()
+
+	# Set up the detected SDL as the SDL2::SDL2 INTERFACE target if it hasn't already been created. This is done for
+	# consistent referencing across the CMake code regardless of the CMake version used.
+	if(NOT TARGET SDL2::SDL2)
+		add_library(SDL2::SDL2 INTERFACE IMPORTED)
+		set_target_properties(SDL2::SDL2 PROPERTIES
+			INTERFACE_LINK_LIBRARIES "${SDL2_LIBRARIES}"
+			INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIRS}"
+		)
+	endif()
+
+	# SDL_GL2 backend requires GLEW
+	if(RMLUI_BACKEND STREQUAL "SDL_GL2" AND NOT TARGET GLEW::GLEW)
+		find_package(GLEW)
+		if(NOT TARGET GLEW::GLEW)
+			report_dependency_not_found("GLEW" GLEW::GLEW)
+		endif()
+	endif()
+
+	# Check version requirement for the SDL renderer
+	if(RMLUI_BACKEND STREQUAL "SDL_SDLrenderer" AND SDL2_VERSION VERSION_LESS "2.0.20")
+		message(FATAL_ERROR "SDL native renderer backend (${RMLUI_BACKEND}) requires SDL 2.0.20 (found ${SDL2_VERSION}).")
+	endif()
+
+	# List of SDL backends that require SDL_image to work with samples
+	set(RMLUI_SDL_BACKENDS_WITH_SDLIMAGE "SDL_GL2" "SDL_GL3" "SDL_SDLrenderer")
+
+	# Determine if the selected SDL backend requires SDL_image
+	if(RMLUI_BACKEND IN_LIST RMLUI_SDL_BACKENDS_WITH_SDLIMAGE)
+		set(RMLUI_SDLIMAGE_REQUIRED TRUE)
+	else()
+		set(RMLUI_SDLIMAGE_REQUIRED FALSE)
+	endif()
+	unset(RMLUI_SDL_BACKENDS_WITH_SDLIMAGE)
+
+	# Require SDL_image if needed
+	if(RMLUI_SDLIMAGE_REQUIRED)
+		find_package("SDL2_image")
+		report_dependency_found_or_error("SDL2_image" SDL2_image::SDL2_image)
+	endif()
+endif()
+
+# GLFW
+if(RMLUI_BACKEND MATCHES "^GLFW")
+	find_package("glfw3" "3.3")
+
+	# Instead of relying on the <package_name>_FOUND variable, we check directly for the target
+	if(NOT TARGET glfw)
+		report_dependency_found_or_error("GLFW" glfw)
+	endif()
+endif()
+
+# SFML
+if(RMLUI_BACKEND MATCHES "^SFML")
+	#[[
+		Starting with SFML 2.7, the recommended method to find the library is using
+		the official config file which sets up targets for each module of the library.
+		The names of the targets follow the namespaced target names convention.
+
+		When one of the required modules isn't present as a SFML::<module> target,
+		that means SFML < 2.7 is being used and we need to set up the target(s) by ourselves.
+
+		In SFML 2.5 the first iteration of the SFMLConfig.cmake file was introduced, which
+		uses a target-oriented approach to exposing the different modules of SFML but it doesn't
+		use the same names as the config file from SFML 2.7.
+	]]
+
+	# List of required components in capital case
+	set(RMLUI_SFML_REQUIRED_COMPONENTS "Graphics" "Window" "System")
+
+	# Run find package with component names both capitalized and lower-cased
+	find_package("SFML" "2" COMPONENTS ${RMLUI_SFML_REQUIRED_COMPONENTS} QUIET)
+	if(NOT SFML_FOUND)
+		list(TRANSFORM RMLUI_SFML_REQUIRED_COMPONENTS TOLOWER OUTPUT_VARIABLE RMLUI_SFML_REQUIRED_COMPONENTS_LOWER_CASE)
+		find_package("SFML" "2" COMPONENTS ${RMLUI_SFML_REQUIRED_COMPONENTS_LOWER_CASE} QUIET)
+	endif()
+
+	# Since we are using find_package() in basic mode, we can check the _FOUND variable
+	if(NOT SFML_FOUND)
+		report_dependency_not_found("SFML" SFML::SFML)
+	endif()
+
+	#[[
+		Since the RmlUi CMake project uses the SFML 2.7 namespaced target names, if the version is lower wrappers
+		need to be set up.
+
+		Because we always require the window module, we can use it to determine which iteration of the config.
+	]]
+
+	# If any of the mandatory SFML 2.7 targets isn't present, assume SFML < 2.7 has been found and set up wrappers
+	if(NOT TARGET SFML::Window)
+		#[[
+			If sfml-window exists, then that means the version is either SFML 2.5 or 2.6 which set up
+			module-specific CMake targets but with different names using a config file.
+
+			Therefore, we need to alias the target names to match those declared by SFML 2.7 and used by RmlUi.
+		]]
+
+		# For each SFML component the project requires
+		foreach(rmlui_sfml_component ${RMLUI_SFML_REQUIRED_COMPONENTS})
+			# Make the component name lowercase
+			string(TOLOWER ${rmlui_sfml_component} rmlui_sfml_component_lower)
+
+			if(TARGET sfml-${rmlui_sfml_component_lower})
+				#[[
+					RMLUI_CMAKE_MINIMUM_VERSION_RAISE_NOTICE:
+					Because the target CMake version is 3.10, we can't alias non-global targets nor global imported targets.
+
+					Promoting an imported target to the global scope without it being necessary can cause undesired behavior,
+					specially when the project is consumed as a subdirectory inside another CMake project, therefore is not
+					recommended. Instead of that, we pseudo-alias the target creating a second INTERFACE target with alias name.
+					More info: https://cmake.org/cmake/help/latest/command/add_library.html#alias-libraries
+				]]
+
+				# If the target exists, alias it
+				add_library(SFML::${rmlui_sfml_component} INTERFACE IMPORTED)
+				target_link_libraries(SFML::${rmlui_sfml_component} INTERFACE sfml-${rmlui_sfml_component_lower})
+			endif()
+		endforeach()
+	endif()
+endif()
+
+# X11
+if(RMLUI_BACKEND MATCHES "^X11")
+	find_package("X11")
+endif()
+
+# --- Rendering APIs ---
+# OpenGL
+
+# Set preferred OpenGL ABI on Linux for target OpenGL::GL
+# More info: https://cmake.org/cmake/help/latest/module/FindOpenGL.html#linux-specific
+# RMLUI_CMAKE_MINIMUM_VERSION_RAISE_NOTICE:
+# Can remove this with CMake 3.11 as this has become the default. See policy CMP0072.
+set(OpenGL_GL_PREFERENCE "GLVND")
+
+if(RMLUI_BACKEND MATCHES "GL2$")
+	find_package("OpenGL" "2")
+	report_dependency_found_or_error("OpenGL" OpenGL::GL)
+endif()
+
+if(RMLUI_BACKEND MATCHES "GL3$")
+	find_package("OpenGL" "3")
+	report_dependency_found_or_error("OpenGL" OpenGL::GL)
+endif()

+ 37 - 0
CMake/DependenciesForShell.cmake

@@ -0,0 +1,37 @@
+#[[
+	Set up external dependencies required by the shell utility library used by the samples.
+]]
+
+# RMLUI_CMAKE_MINIMUM_VERSION_RAISE_NOTICE:
+# CMake >= 3.18 introduces the REQUIRED option for find_library() calls. Guaranteeing the presence of the platform SDK
+# by making these calls to find_library() REQUIRED should be investigated.
+# More info: https://cmake.org/cmake/help/latest/command/find_library.html
+
+# Link against required libraries from Windows
+if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
+	# Required to use the functions from the shlwapi.h header
+	find_library(Shlwapi NAMES "Shlwapi" "Shlwapi.lib" "Shlwapi.dll")
+	if(NOT Shlwapi)
+		# Many platform libraries are still available to linkers even if CMake cannot find them
+		# Ignore the fact that the Shlwapi wasn't found and try to link against it anyway
+		set(Shlwapi "Shlwapi")
+	endif()
+
+	# Set up wrapper target
+	add_library(Windows::Shell::LightweightUtility INTERFACE IMPORTED)
+	target_link_libraries(Windows::Shell::LightweightUtility INTERFACE ${Shlwapi})
+
+	# Link against required libraries from macOS
+elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+	# Required to use the functions from the Cocoa framework
+	find_library(Cocoa NAMES "Cocoa" "Cocoa.framework")
+	if(NOT Cocoa)
+		# Many platform libraries are still available to linkers even if CMake cannot find them
+		# Ignore the fact that the Cocoa wasn't found and try to link against it anyway
+		set(Cocoa "Cocoa")
+	endif()
+
+	# Set up wrapper target
+	add_library(macOS::Cocoa INTERFACE IMPORTED)
+	target_link_libraries(macOS::Cocoa INTERFACE ${Cocoa})
+endif()

+ 24 - 0
CMake/DependenciesForTests.cmake

@@ -0,0 +1,24 @@
+#[[
+	Set up dependencies for the RmlUi tests. The dependencies are all built-in header-only libraries.
+]]
+function(add_builtin_header_only_tests_dependency NAME)
+	set(DEPENDENCY_PATH "${PROJECT_SOURCE_DIR}/Tests/Dependencies/${NAME}")
+	set(DEPENDENCY_TARGET "${NAME}::${NAME}")
+	add_library(${DEPENDENCY_TARGET} IMPORTED INTERFACE)
+	set_property(TARGET ${DEPENDENCY_TARGET} PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${DEPENDENCY_PATH}")
+endfunction()
+
+add_builtin_header_only_tests_dependency("doctest")
+add_builtin_header_only_tests_dependency("nanobench")
+add_builtin_header_only_tests_dependency("lodepng")
+add_builtin_header_only_tests_dependency("trompeloeil")
+
+# Include doctest's discovery module
+include("${PROJECT_SOURCE_DIR}/Tests/Dependencies/doctest/cmake/doctest.cmake")
+
+if(MSVC)
+	target_compile_definitions(doctest::doctest INTERFACE DOCTEST_CONFIG_USE_STD_HEADERS)
+endif()
+if(NOT RMLUI_RTTI_AND_EXCEPTIONS)
+	target_compile_definitions(doctest::doctest INTERFACE DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS)
+endif()

+ 0 - 597
CMake/FileList.cmake

@@ -1,597 +0,0 @@
-# This file was auto-generated with gen_filelists.sh
-
-set(Core_HDR_FILES
-    ${PROJECT_SOURCE_DIR}/Source/Core/Clock.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/ComputeProperty.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/ContextInstancerDefault.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/DataController.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/DataControllerDefault.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/DataExpression.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/DataModel.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/DataView.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/DataViewDefault.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/DecoratorGradient.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/DecoratorNinePatch.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/DecoratorShader.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/DecoratorTiled.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/DecoratorTiledBox.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/DecoratorTiledHorizontal.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/DecoratorTiledImage.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/DecoratorTiledVertical.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/DocumentHeader.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/ElementAnimation.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/ElementBackgroundBorder.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/ElementDefinition.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/ElementEffects.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/ElementHandle.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/ElementImage.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/ElementLabel.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/ElementTextSelection.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/InputType.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/InputTypeButton.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/InputTypeCheckbox.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/InputTypeRadio.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/InputTypeRange.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/InputTypeSubmit.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/InputTypeText.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/WidgetDropDown.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/WidgetSlider.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/WidgetTextInput.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/WidgetTextInputMultiLine.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/WidgetTextInputSingleLine.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/WidgetTextInputSingleLinePassword.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/XMLNodeHandlerSelect.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/XMLNodeHandlerTabSet.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/XMLNodeHandlerTextArea.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/ElementStyle.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/EventDispatcher.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/EventInstancerDefault.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/EventSpecification.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/FileInterfaceDefault.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/FilterBasic.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/FilterBlur.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/FilterDropShadow.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/FontEffectBlur.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/FontEffectGlow.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/FontEffectOutline.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/FontEffectShadow.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/GeometryBackgroundBorder.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/GeometryBoxShadow.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/IdNameMap.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/BlockContainer.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/BlockFormattingContext.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/ContainerBox.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/FlexFormattingContext.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/FloatedBoxSpace.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/FormattingContext.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/InlineBox.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/InlineContainer.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/InlineLevelBox.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/InlineTypes.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/LayoutBox.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/LayoutDetails.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/LayoutEngine.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/LayoutPools.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/LineBox.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/ReplacedFormattingContext.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/TableFormattingContext.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/TableFormattingDetails.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/LogDefault.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Memory.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/PluginRegistry.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Pool.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/precompiled.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/PropertiesIterator.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/PropertyParserAnimation.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/PropertyParserBoxShadow.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/PropertyParserColorStopList.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/PropertyParserColour.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/PropertyParserDecorator.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/PropertyParserFilter.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/PropertyParserFontEffect.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/PropertyParserKeyword.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/PropertyParserNumber.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/PropertyParserRatio.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/PropertyParserString.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/PropertyParserTransform.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/PropertyShorthandDefinition.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/RenderManagerAccess.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/ScrollController.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/StreamFile.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/StyleSheetFactory.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/StyleSheetNode.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/StyleSheetParser.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/StyleSheetSelector.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/Template.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/TemplateCache.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/TextureDatabase.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/TextureLayout.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/TextureLayoutRectangle.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/TextureLayoutRow.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/TextureLayoutTexture.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/TransformState.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/TransformUtilities.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/WidgetScroll.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/XMLNodeHandlerBody.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/XMLNodeHandlerDefault.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/XMLNodeHandlerHead.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/XMLNodeHandlerTemplate.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/XMLParseTools.h
-)
-
-set(MASTER_Core_PUB_HDR_FILES
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core.h
-)
-
-set(Core_PUB_HDR_FILES
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Config/Config.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Animation.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/BaseXMLParser.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Box.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/CallbackTexture.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Colour.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Colour.inl
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/CompiledFilterShader.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/ComputedValues.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Containers/itlib/flat_map.hpp
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Containers/itlib/flat_set.hpp
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Containers/robin_hood.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Context.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/ContextInstancer.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/ConvolutionFilter.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Core.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/DataModelHandle.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/DataStructHandle.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/DataTypeRegister.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/DataTypes.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/DataVariable.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Debug.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/DecorationTypes.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Decorator.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Dictionary.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/EffectSpecification.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Element.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Element.inl
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/ElementDocument.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/ElementInstancer.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Elements/ElementForm.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Elements/ElementFormControl.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Elements/ElementFormControlInput.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Elements/ElementFormControlSelect.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Elements/ElementFormControlTextArea.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Elements/ElementProgress.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Elements/ElementTabSet.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/ElementScroll.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/ElementText.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/ElementUtilities.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Event.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/EventInstancer.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/EventListener.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/EventListenerInstancer.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Factory.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/FileInterface.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Filter.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/FontEffect.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/FontEffectInstancer.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/FontEngineInterface.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/FontGlyph.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/FontMetrics.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Geometry.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Header.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/ID.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Input.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Log.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Math.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Matrix4.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Matrix4.inl
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Mesh.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/MeshUtilities.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/NumericValue.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/ObserverPtr.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Platform.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Plugin.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Profiling.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/PropertiesIteratorView.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Property.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/PropertyDefinition.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/PropertyDictionary.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/PropertyIdSet.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/PropertyParser.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/PropertySpecification.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Rectangle.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/RenderInterface.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/RenderInterfaceCompatibility.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/RenderManager.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/ScriptInterface.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/ScrollTypes.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Span.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Spritesheet.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/StableVector.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Stream.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/StreamMemory.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/StringUtilities.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/StyleSheet.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/StyleSheetContainer.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/StyleSheetSpecification.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/StyleSheetTypes.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/StyleTypes.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/SystemInterface.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Texture.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/TextShapingContext.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Traits.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Transform.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/TransformPrimitive.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Tween.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/TypeConverter.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/TypeConverter.inl
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Types.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/UniqueRenderResource.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Unit.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/URL.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Utilities.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Variant.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Variant.inl
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Vector2.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Vector2.inl
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Vector3.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Vector3.inl
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Vector4.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Vector4.inl
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Vertex.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/XMLNodeHandler.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/XMLParser.h
-)
-
-set(Core_SRC_FILES
-    ${PROJECT_SOURCE_DIR}/Source/Core/BaseXMLParser.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Box.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/CallbackTexture.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Clock.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/CompiledFilterShader.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/ComputedValues.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/ComputeProperty.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Context.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/ContextInstancer.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/ContextInstancerDefault.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/ConvolutionFilter.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Core.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/DataController.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/DataControllerDefault.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/DataExpression.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/DataModel.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/DataModelHandle.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/DataTypeRegister.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/DataVariable.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/DataView.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/DataViewDefault.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Decorator.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/DecoratorGradient.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/DecoratorNinePatch.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/DecoratorShader.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/DecoratorTiled.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/DecoratorTiledBox.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/DecoratorTiledHorizontal.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/DecoratorTiledImage.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/DecoratorTiledVertical.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/DocumentHeader.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/EffectSpecification.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Element.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/ElementAnimation.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/ElementBackgroundBorder.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/ElementDefinition.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/ElementDocument.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/ElementEffects.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/ElementHandle.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/ElementInstancer.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/ElementForm.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/ElementFormControl.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/ElementFormControlInput.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/ElementFormControlSelect.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/ElementFormControlTextArea.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/ElementImage.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/ElementLabel.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/ElementProgress.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/ElementTabSet.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/ElementTextSelection.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/InputType.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/InputTypeButton.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/InputTypeCheckbox.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/InputTypeRadio.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/InputTypeRange.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/InputTypeSubmit.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/InputTypeText.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/WidgetDropDown.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/WidgetSlider.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/WidgetTextInput.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/WidgetTextInputMultiLine.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/WidgetTextInputSingleLine.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/WidgetTextInputSingleLinePassword.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/XMLNodeHandlerSelect.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/XMLNodeHandlerTabSet.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Elements/XMLNodeHandlerTextArea.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/ElementScroll.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/ElementStyle.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/ElementText.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/ElementUtilities.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Event.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/EventDispatcher.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/EventInstancer.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/EventInstancerDefault.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/EventListenerInstancer.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/EventSpecification.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Factory.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/FileInterface.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/FileInterfaceDefault.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Filter.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/FilterBasic.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/FilterBlur.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/FilterDropShadow.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/FontEffect.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/FontEffectBlur.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/FontEffectGlow.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/FontEffectInstancer.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/FontEffectOutline.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/FontEffectShadow.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/FontEngineInterface.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Geometry.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/GeometryBackgroundBorder.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/GeometryBoxShadow.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/BlockContainer.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/BlockFormattingContext.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/ContainerBox.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/FlexFormattingContext.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/FloatedBoxSpace.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/FormattingContext.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/InlineBox.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/InlineContainer.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/InlineLevelBox.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/LayoutBox.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/LayoutDetails.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/LayoutEngine.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/LayoutPools.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/LineBox.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/ReplacedFormattingContext.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/TableFormattingContext.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Layout/TableFormattingDetails.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Log.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/LogDefault.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Math.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Memory.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/MeshUtilities.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/ObserverPtr.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Plugin.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/PluginRegistry.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Profiling.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/PropertiesIteratorView.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Property.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/PropertyDefinition.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/PropertyDictionary.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/PropertyParserAnimation.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/PropertyParserBoxShadow.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/PropertyParserColorStopList.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/PropertyParserColour.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/PropertyParserDecorator.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/PropertyParserFilter.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/PropertyParserFontEffect.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/PropertyParserKeyword.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/PropertyParserNumber.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/PropertyParserRatio.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/PropertyParserString.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/PropertyParserTransform.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/PropertySpecification.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/RenderInterface.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/RenderInterfaceCompatibility.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/RenderManager.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/RenderManagerAccess.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/ScrollController.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Spritesheet.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Stream.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/StreamFile.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/StreamMemory.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/StringUtilities.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/StyleSheet.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/StyleSheetContainer.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/StyleSheetFactory.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/StyleSheetNode.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/StyleSheetParser.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/StyleSheetSelector.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/StyleSheetSpecification.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/SystemInterface.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Template.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/TemplateCache.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Texture.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/TextureDatabase.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/TextureLayout.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/TextureLayoutRectangle.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/TextureLayoutRow.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/TextureLayoutTexture.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Transform.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/TransformPrimitive.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/TransformState.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/TransformUtilities.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Tween.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/TypeConverter.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/URL.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/Variant.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/WidgetScroll.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/XMLNodeHandler.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/XMLNodeHandlerBody.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/XMLNodeHandlerDefault.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/XMLNodeHandlerHead.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/XMLNodeHandlerTemplate.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/XMLParser.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/XMLParseTools.cpp
-)
-
-set(Debugger_HDR_FILES
-    ${PROJECT_SOURCE_DIR}/Source/Debugger/BeaconSource.h
-    ${PROJECT_SOURCE_DIR}/Source/Debugger/CommonSource.h
-    ${PROJECT_SOURCE_DIR}/Source/Debugger/DebuggerPlugin.h
-    ${PROJECT_SOURCE_DIR}/Source/Debugger/DebuggerSystemInterface.h
-    ${PROJECT_SOURCE_DIR}/Source/Debugger/ElementContextHook.h
-    ${PROJECT_SOURCE_DIR}/Source/Debugger/ElementInfo.h
-    ${PROJECT_SOURCE_DIR}/Source/Debugger/ElementLog.h
-    ${PROJECT_SOURCE_DIR}/Source/Debugger/FontSource.h
-    ${PROJECT_SOURCE_DIR}/Source/Debugger/Geometry.h
-    ${PROJECT_SOURCE_DIR}/Source/Debugger/InfoSource.h
-    ${PROJECT_SOURCE_DIR}/Source/Debugger/LogSource.h
-    ${PROJECT_SOURCE_DIR}/Source/Debugger/MenuSource.h
-)
-
-set(MASTER_Debugger_PUB_HDR_FILES
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Debugger.h
-)
-
-set(Debugger_PUB_HDR_FILES
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Debugger/Debugger.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Debugger/Header.h
-)
-
-set(Debugger_SRC_FILES
-    ${PROJECT_SOURCE_DIR}/Source/Debugger/Debugger.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Debugger/DebuggerPlugin.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Debugger/DebuggerSystemInterface.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Debugger/ElementContextHook.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Debugger/ElementInfo.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Debugger/ElementLog.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Debugger/Geometry.cpp
-)
-
-if(NOT NO_FONT_INTERFACE_DEFAULT)
-    set(Core_HDR_FILES
-        ${Core_HDR_FILES}
-        ${PROJECT_SOURCE_DIR}/Source/Core/FontEngineDefault/FontEngineInterfaceDefault.h
-        ${PROJECT_SOURCE_DIR}/Source/Core/FontEngineDefault/FontFace.h
-        ${PROJECT_SOURCE_DIR}/Source/Core/FontEngineDefault/FontFaceHandleDefault.h
-        ${PROJECT_SOURCE_DIR}/Source/Core/FontEngineDefault/FontFaceLayer.h
-        ${PROJECT_SOURCE_DIR}/Source/Core/FontEngineDefault/FontFamily.h
-        ${PROJECT_SOURCE_DIR}/Source/Core/FontEngineDefault/FontProvider.h
-        ${PROJECT_SOURCE_DIR}/Source/Core/FontEngineDefault/FontTypes.h
-        ${PROJECT_SOURCE_DIR}/Source/Core/FontEngineDefault/FreeTypeInterface.h
-    )
-
-    set(Core_SRC_FILES
-        ${Core_SRC_FILES}
-        ${PROJECT_SOURCE_DIR}/Source/Core/FontEngineDefault/FontEngineInterfaceDefault.cpp
-        ${PROJECT_SOURCE_DIR}/Source/Core/FontEngineDefault/FontFace.cpp
-        ${PROJECT_SOURCE_DIR}/Source/Core/FontEngineDefault/FontFaceHandleDefault.cpp
-        ${PROJECT_SOURCE_DIR}/Source/Core/FontEngineDefault/FontFaceLayer.cpp
-        ${PROJECT_SOURCE_DIR}/Source/Core/FontEngineDefault/FontFamily.cpp
-        ${PROJECT_SOURCE_DIR}/Source/Core/FontEngineDefault/FontProvider.cpp
-        ${PROJECT_SOURCE_DIR}/Source/Core/FontEngineDefault/FreeTypeInterface.cpp
-    )
-endif()
-
-set(Lua_HDR_FILES
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Colourb.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Colourf.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Context.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/ContextDocumentsProxy.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Document.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Element.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/ElementAttributesProxy.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/ElementChildNodesProxy.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/ElementInstancer.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Elements/As.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Elements/ElementForm.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Elements/ElementFormControl.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Elements/ElementFormControlInput.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Elements/ElementFormControlSelect.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Elements/ElementFormControlTextArea.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Elements/ElementTabSet.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Elements/SelectOptionsProxy.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/ElementStyleProxy.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/ElementText.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Event.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/EventParametersProxy.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/GlobalLuaFunctions.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Log.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/LuaDataModel.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/LuaDocument.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/LuaDocumentElementInstancer.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/LuaElementInstancer.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/LuaEventListener.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/LuaEventListenerInstancer.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/LuaPlugin.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Pairs.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/RmlUi.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/RmlUiContextsProxy.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Vector2f.h
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Vector2i.h
-)
-
-set(Lua_PUB_HDR_FILES
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Lua/Header.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Lua/IncludeLua.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Lua/Interpreter.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Lua/Lua.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Lua/LuaType.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Lua/Utilities.h
-)
-
-set(Lua_SRC_FILES
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Colourb.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Colourf.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Context.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/ContextDocumentsProxy.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Document.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Element.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/ElementAttributesProxy.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/ElementChildNodesProxy.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/ElementInstancer.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Elements/ElementForm.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Elements/ElementFormControl.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Elements/ElementFormControlInput.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Elements/ElementFormControlSelect.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Elements/ElementFormControlTextArea.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Elements/ElementTabSet.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Elements/SelectOptionsProxy.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/ElementStyleProxy.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/ElementText.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Event.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/EventParametersProxy.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/GlobalLuaFunctions.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Interpreter.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Log.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Lua.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/LuaDataModel.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/LuaDocument.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/LuaDocumentElementInstancer.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/LuaElementInstancer.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/LuaEventListener.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/LuaEventListenerInstancer.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/LuaPlugin.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/LuaType.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/RmlUi.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/RmlUiContextsProxy.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Utilities.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Vector2f.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lua/Vector2i.cpp
-)
-
-set(Lottie_HDR_FILES
-    ${PROJECT_SOURCE_DIR}/Source/Lottie/LottiePlugin.h
-)
-
-set(Lottie_PUB_HDR_FILES
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Lottie/ElementLottie.h
-)
-
-set(Lottie_SRC_FILES
-    ${PROJECT_SOURCE_DIR}/Source/Lottie/ElementLottie.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Lottie/LottiePlugin.cpp
-)
-
-set(SVG_HDR_FILES
-    ${PROJECT_SOURCE_DIR}/Source/SVG/SVGPlugin.h
-)
-
-set(SVG_PUB_HDR_FILES
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/SVG/ElementSVG.h
-)
-
-set(SVG_SRC_FILES
-    ${PROJECT_SOURCE_DIR}/Source/SVG/ElementSVG.cpp
-    ${PROJECT_SOURCE_DIR}/Source/SVG/SVGPlugin.cpp
-)
-

+ 63 - 0
CMake/Modules/Emscripten/FindFreetype.cmake

@@ -0,0 +1,63 @@
+#[[
+	Custom find module for Freetype for Emscripten compilation.
+
+	Input variables:
+		none
+	Output variables:
+		Freetype_FOUND
+		FREETYPE_VERSION_STRING
+
+	Resulting targets:
+		Freetype::Freetype
+
+	More info:
+	https://emscripten.org/docs/porting/multimedia_and_graphics/OpenGL-support.html
+]]
+
+include(FindPackageHandleStandardArgs)
+include(FindPackageMessage)
+
+if(NOT TARGET Freetype::Freetype)
+	# If no version was specified, set default
+	if(NOT DEFINED Freetype_FIND_VERSION)
+		set(Freetype_FIND_VERSION "2")
+	endif()
+
+	# Check if requested Freetype version is valid
+	# Emscripten SDK only provides Freetype 2.x
+	if((Freetype_FIND_VERSION VERSION_LESS "2") OR (Freetype_FIND_VERSION VERSION_GREATER_EQUAL "3"))
+		message(FATAL_ERROR "The requested Freetype version ${Freetype_FIND_VERSION} is invalid.")
+	endif()
+
+	# Emscripten includes Freetype support as part of it's SDK, meaning there's no need to find it
+	set(Freetype_FOUND TRUE)
+	add_library(Freetype::Freetype INTERFACE IMPORTED)
+
+	# Set found Freetype version
+	# Version set based on latest Emscripten SDK at the time of writing this file
+	set(FREETYPE_VERSION_STRING "2.6")
+
+	# Enable compilation and linking against Freetype
+	target_compile_options(Freetype::Freetype INTERFACE "-sUSE_FREETYPE=1")
+	target_link_libraries(Freetype::Freetype INTERFACE "-sUSE_FREETYPE=1")
+
+	# Get final compiler and linker flags to print them
+	get_target_property(Freetype_COMPILE_FLAGS Freetype::Freetype "INTERFACE_COMPILE_OPTIONS")
+	get_target_property(Freetype_LINK_FLAGS Freetype::Freetype "INTERFACE_LINK_OPTIONS")
+
+	find_package_message(
+		"Freetype"
+		"Freetype ${FREETYPE_VERSION_STRING} has been found as part of the Emscripten SDK."
+		"[${Freetype_COMPILE_FLAGS}][${Freetype_LINK_FLAGS}]"
+	)
+
+	# Clean scope
+	unset(Freetype_COMPILE_FLAGS)
+	unset(Freetype_LINK_FLAGS)
+else()
+	# Since the target already exists, we declare it as found
+	set(Freetype_FOUND TRUE)
+	if(NOT DEFINED FREETYPE_VERSION_STRING)
+		set(FREETYPE_VERSION_STRING "UNKNOWN")
+	endif()
+endif()

+ 84 - 0
CMake/Modules/Emscripten/FindOpenGL.cmake

@@ -0,0 +1,84 @@
+#[[
+	Custom find module for OpenGL ES for Emscripten compilation.
+
+	Input variables:
+		OpenGL_ENABLE_EMULATION
+
+	Output variables:
+		OpenGL_FOUND
+		OpenGL_VERSION
+
+	Resulting targets:
+		OpenGL::GL
+
+	More info:
+	https://emscripten.org/docs/porting/multimedia_and_graphics/OpenGL-support.html
+]]
+
+include(FindPackageHandleStandardArgs)
+include(FindPackageMessage)
+
+if(NOT TARGET OpenGL::GL)
+	# If no version was specified, set default
+	if(NOT DEFINED OpenGL_FIND_VERSION)
+		set(OpenGL_FIND_VERSION "3")
+	endif()
+	if(NOT DEFINED OpenGL_ENABLE_EMULATION)
+		set(OpenGL_ENABLE_EMULATION ON)
+	endif()
+
+	# Check if requested OpenGL version is valid
+	if((OpenGL_FIND_VERSION VERSION_LESS "1") OR (OpenGL_FIND_VERSION VERSION_GREATER_EQUAL "4"))
+		message(FATAL_ERROR "The requested OpenGL version ${OpenGL_FIND_VERSION} is invalid.")
+	endif()
+
+	# Emscripten includes OpenGL ES support as part of it's SDK, meaning there's no need to find it
+	set(OpenGL_FOUND TRUE)
+	add_library(OpenGL::GL INTERFACE IMPORTED)
+
+	# Set found OpenGL version
+	if((OpenGL_FIND_VERSION VERSION_GREATER_EQUAL "1") AND (OpenGL_FIND_VERSION VERSION_LESS "2"))
+		set(OpenGL_VERSION "1")
+	elseif((OpenGL_FIND_VERSION VERSION_GREATER_EQUAL "2") AND (OpenGL_FIND_VERSION VERSION_LESS "3"))
+		set(OpenGL_VERSION "2")
+	elseif((OpenGL_FIND_VERSION VERSION_GREATER_EQUAL "3") AND (OpenGL_FIND_VERSION VERSION_LESS "4"))
+		set(OpenGL_VERSION "3")
+	endif()
+
+	#[[
+		The Emscripten SDK already makes OpenGL available by default without any additional configuration.
+		However, additional settings might be needed in some cases.
+	]]
+
+	# Handle OpenGL 1 edge case
+	# More info: https://emscripten.org/docs/porting/multimedia_and_graphics/OpenGL-support.html#emulation-of-older-desktop-opengl-api-features
+	if(OpenGL_VERSION VERSION_EQUAL "1")
+		target_link_libraries(OpenGL::GL INTERFACE "-sLEGACY_GL_EMULATION")
+	endif()
+
+	# Handle OpenGL ES software emulation
+	# More info: https://emscripten.org/docs/porting/multimedia_and_graphics/OpenGL-support.html#opengl-es-2-0-3-0-emulation
+	if(OpenGL_ENABLE_EMULATION AND OpenGL_VERSION VERSION_GREATER_EQUAL "2")
+		target_link_libraries(OpenGL::GL INTERFACE "-sFULL_ES${OpenGL_VERSION}")
+	endif()
+
+	# Get final compiler and linker flags to print them
+	get_target_property(OpenGL_COMPILE_FLAGS OpenGL::GL "INTERFACE_COMPILE_OPTIONS")
+	get_target_property(OpenGL_LINK_FLAGS OpenGL::GL "INTERFACE_LINK_OPTIONS")
+
+	find_package_message(
+		"OpenGL"
+		"OpenGL ${OpenGL_VERSION} has been found as part of the Emscripten SDK."
+		"[${OpenGL_COMPILE_FLAGS}][${OpenGL_LINK_FLAGS}]"
+	)
+
+	# Clean scope
+	unset(OpenGL_COMPILE_FLAGS)
+	unset(OpenGL_LINK_FLAGS)
+else()
+	# Since the target already exists, we declare it as found
+	set(OpenGL_FOUND TRUE)
+	if(NOT DEFINED OpenGL_VERSION)
+		set(OpenGL_VERSION "UNKNOWN")
+	endif()
+endif()

+ 66 - 0
CMake/Modules/Emscripten/FindSDL2.cmake

@@ -0,0 +1,66 @@
+#[[
+	Custom find module for SDL for Emscripten compilation.
+
+	Input variables:
+		none
+	Output variables:
+		SDL2_FOUND
+		SDL2_VERSION
+
+	Resulting targets:
+		SDL2::SDL2
+
+	More info:
+	https://emscripten.org/docs/porting/multimedia_and_graphics/OpenGL-support.html
+]]
+
+include(FindPackageHandleStandardArgs)
+include(FindPackageMessage)
+
+if(NOT TARGET SDL2::SDL2)
+	# If no version was specified, set default
+	if(NOT DEFINED SDL2_FIND_VERSION)
+		set(SDL2_FIND_VERSION "2")
+	endif()
+
+	# Check if requested SDL version is valid
+	if((SDL2_FIND_VERSION VERSION_LESS "2") OR (SDL2_FIND_VERSION VERSION_GREATER_EQUAL "3"))
+		message(FATAL_ERROR "The requested SDL2 version ${SDL2_FIND_VERSION} is invalid.")
+	endif()
+
+	# Emscripten includes SDL support as part of it's SDK, meaning there's no need to find it
+	set(SDL2_FOUND TRUE)
+	add_library(SDL2::SDL2 INTERFACE IMPORTED)
+
+	# Set found SDL version based on latest Emscripten SDK at the time of writing this file
+	# Version set based on latest Emscripten SDK at the time of writing this file
+	set(SDL2_VERSION "2.24.2")
+
+	# Version number to pass to compiler
+	set(SDL2_EMSCRIPTEN_COMPILER_SELECTED_VERSION "2")
+
+	# Enable compilation and linking against SDL
+	target_compile_options(SDL2::SDL2 INTERFACE "-sUSE_SDL=${SDL2_EMSCRIPTEN_COMPILER_SELECTED_VERSION}")
+	target_link_libraries(SDL2::SDL2 INTERFACE "-sUSE_SDL=${SDL2_EMSCRIPTEN_COMPILER_SELECTED_VERSION}")
+
+	# Get final compiler and linker flags to print them
+	get_target_property(SDL2_COMPILE_FLAGS SDL2::SDL2 "INTERFACE_COMPILE_OPTIONS")
+	get_target_property(SDL2_LINK_FLAGS SDL2::SDL2 "INTERFACE_LINK_OPTIONS")
+
+	find_package_message(
+		"SDL2"
+		"SDL ${SDL2_VERSION} has been found as part of the Emscripten SDK."
+		"[${SDL2_COMPILE_FLAGS}][${SDL2_LINK_FLAGS}]"
+	)
+
+	# Clean scope
+	unset(SDL2_COMPILE_FLAGS)
+	unset(SDL2_COMPILE_FLAGS)
+	unset(SDL2_EMSCRIPTEN_COMPILER_SELECTED_VERSION)
+else()
+	# Since the target already exists, we declare it as found
+	set(SDL2_FOUND TRUE)
+	if(NOT DEFINED SDL2_VERSION)
+		set(SDL2_VERSION "UNKNOWN")
+	endif()
+endif()

+ 82 - 0
CMake/Modules/Emscripten/FindSDL2_image.cmake

@@ -0,0 +1,82 @@
+#[[
+	Custom find module for SDL_image for Emscripten compilation.
+
+	Input variables:
+		SDL2_image_FORMATS
+
+	Output variables:
+		SDL2_image_FOUND
+		SDL2_image_VERSION
+
+	Resulting targets:
+		SDL2_image::SDL2_image
+
+	More info:
+	https://emscripten.org/docs/porting/multimedia_and_graphics/OpenGL-support.html
+]]
+
+include(FindPackageHandleStandardArgs)
+include(FindPackageMessage)
+
+if(NOT TARGET SDL2_image::SDL2_image)
+	# If no version was specified, set default
+	if(NOT DEFINED SDL2_image_FIND_VERSION)
+		set(SDL2_image_FIND_VERSION "2")
+	endif()
+	if(NOT DEFINED SDL2_image_FORMATS)
+		set(SDL2_image_FORMATS "[tga]")
+	endif()
+
+	# Check if requested SDL version is valid
+	if((SDL2_image_FIND_VERSION VERSION_LESS "2") OR (SDL2_image_FIND_VERSION VERSION_GREATER_EQUAL "3"))
+		message(FATAL_ERROR "The requested SDL2_image version ${SDL2_image_FIND_VERSION} is invalid.")
+	endif()
+
+	message(NOTICE
+		"SDL_image with Emscripten can only be used if SDL usage is also enabled. "
+		"The version number of both libraries must match as well."
+	)
+
+	# Emscripten includes SDL support as part of it's SDK, meaning there's no need to find it
+	set(SDL2_image_FOUND TRUE)
+	add_library(SDL2_image::SDL2_image INTERFACE IMPORTED)
+
+	# Set found SDL_image version based on latest Emscripten SDK at the time of writing this file
+	# Version set based on latest Emscripten SDK at the time of writing this file
+	set(SDL2_image_VERSION "2.24.2")
+
+	# Version number to pass to compiler
+	set(SDL2_image_EMSCRIPTEN_COMPILER_SELECTED_VERSION "2")
+
+	set(SDL2_image_TARGET_ARGS "-sUSE_SDL_IMAGE=${SDL2_image_EMSCRIPTEN_COMPILER_SELECTED_VERSION}")
+
+	if(SDL2_image_FORMATS)
+		list(APPEND SDL2_image_TARGET_ARGS "-sSDL2_IMAGE_FORMATS=${SDL2_image_FORMATS}")
+	endif()
+
+	# Enable compilation and linking against SDL
+	target_compile_options(SDL2_image::SDL2_image INTERFACE "${SDL2_image_TARGET_ARGS}")
+	target_link_libraries(SDL2_image::SDL2_image INTERFACE "${SDL2_image_TARGET_ARGS}")
+
+	# Get final compiler and linker flags to print them
+	get_target_property(SDL2_image_COMPILE_FLAGS SDL2_image::SDL2_image "INTERFACE_COMPILE_OPTIONS")
+	get_target_property(SDL2_image_LINK_FLAGS SDL2_image::SDL2_image "INTERFACE_LINK_OPTIONS")
+
+	find_package_message(
+		"SDL2_image"
+		"SDL_image ${SDL2_image_VERSION} has been found as part of the Emscripten SDK."
+		"[${SDL2_image_COMPILE_FLAGS}][${SDL2_image_LINK_FLAGS}]"
+	)
+
+	# Clean scope
+	unset(SDL2_image_TARGET_ARGS)
+	unset(SDL2_image_COMPILE_FLAGS)
+	unset(SDL2_image_LINK_FLAGS)
+	unset(SDL2_image_EMSCRIPTEN_COMPILER_SELECTED_VERSION)
+else()
+	# Since the target already exists, we declare it as found
+	set(SDL2_image_FOUND TRUE)
+	if(NOT DEFINED SDL2_image_VERSION)
+		set(SDL2_image_VERSION "UNKNOWN")
+	endif()
+endif()

+ 66 - 0
CMake/Modules/Emscripten/Findglfw3.cmake

@@ -0,0 +1,66 @@
+#[[
+	Custom find module for GLFW for Emscripten compilation.
+
+	Input variables:
+		none
+	Output variables:
+		glfw3_FOUND
+		glfw3_VERSION
+
+	Resulting targets:
+		glfw
+
+	More info:
+	https://emscripten.org/docs/porting/multimedia_and_graphics/OpenGL-support.html
+]]
+
+include(FindPackageHandleStandardArgs)
+include(FindPackageMessage)
+
+if(NOT TARGET glfw)
+	# If no version was specified, set default
+	if(NOT DEFINED glfw3_FIND_VERSION)
+		set(glfw3_FIND_VERSION "1")
+	endif()
+
+	# Check if requested GLFW version is valid
+	if((glfw3_FIND_VERSION VERSION_LESS "3") OR (glfw3_FIND_VERSION VERSION_GREATER_EQUAL "4"))
+		message(FATAL_ERROR "The requested GLFW version ${glfw3_FIND_VERSION} is invalid.")
+	endif()
+
+	# Emscripten includes GLFW support as part of it's SDK, meaning there's no need to find it
+	set(glfw3_FOUND TRUE)
+	add_library(glfw INTERFACE IMPORTED)
+
+	# Set found GLFW version based on latest Emscripten SDK at the time of writing this file
+	# Version set based on latest Emscripten SDK at the time of writing this file
+	set(glfw3_VERSION "3")
+
+	# Version number to pass to compiler
+	set(glfw3_EMSCRIPTEN_COMPILER_SELECTED_VERSION ${glfw3_VERSION})
+
+	# Enable compilation and linking against GLFW
+	target_compile_options(glfw INTERFACE "-sUSE_GLFW=${glfw3_EMSCRIPTEN_COMPILER_SELECTED_VERSION}")
+	target_link_libraries(glfw INTERFACE "-sUSE_GLFW=${glfw3_EMSCRIPTEN_COMPILER_SELECTED_VERSION}")
+
+	# Get final compiler and linker flags to print them
+	get_target_property(glfw3_COMPILE_FLAGS glfw "INTERFACE_COMPILE_OPTIONS")
+	get_target_property(glfw3_LINK_FLAGS glfw "INTERFACE_LINK_OPTIONS")
+
+	find_package_message(
+		"glfw3"
+		"GLFW ${glfw3_VERSION} has been found as part of the Emscripten SDK."
+		"[${glfw3_COMPILE_FLAGS}][${glfw3_LINK_FLAGS}]"
+	)
+
+	# Clean scope
+	unset(glfw3_COMPILE_FLAGS)
+	unset(glfw3_COMPILE_FLAGS)
+	unset(glfw3_EMSCRIPTEN_COMPILER_SELECTED_VERSION)
+else()
+	# Since the target already exists, we declare it as found
+	set(glfw3_FOUND TRUE)
+	if(NOT DEFINED glfw3_VERSION)
+		set(glfw3_VERSION "UNKNOWN")
+	endif()
+endif()

+ 2 - 2
CMake/Modules/FindLuaJIT.cmake

@@ -7,9 +7,9 @@ FIND_PATH(LUAJIT_INCLUDE_DIR NAMES luajit.h PATH_SUFFIXES luajit luajit-2.0 luaj
 SET(_LUAJIT_STATIC_LIBS libluajit-5.1.a libluajit.a liblua51.a)
 SET(_LUAJIT_STATIC_LIBS libluajit-5.1.a libluajit.a liblua51.a)
 SET(_LUAJIT_SHARED_LIBS luajit-5.1 luajit lua51)
 SET(_LUAJIT_SHARED_LIBS luajit-5.1 luajit lua51)
 IF(USE_STATIC_LIBS)
 IF(USE_STATIC_LIBS)
-    FIND_LIBRARY(LUAJIT_LIBRARY NAMES ${_LUAJIT_STATIC_LIBS} ${_LUAJIT_SHARED_LIBS})
+	FIND_LIBRARY(LUAJIT_LIBRARY NAMES ${_LUAJIT_STATIC_LIBS} ${_LUAJIT_SHARED_LIBS})
 ELSE()
 ELSE()
-    FIND_LIBRARY(LUAJIT_LIBRARY NAMES ${_LUAJIT_SHARED_LIBS} ${_LUAJIT_STATIC_LIBS})
+	FIND_LIBRARY(LUAJIT_LIBRARY NAMES ${_LUAJIT_SHARED_LIBS} ${_LUAJIT_STATIC_LIBS})
 ENDIF()
 ENDIF()
 INCLUDE(FindPackageHandleStandardArgs)
 INCLUDE(FindPackageHandleStandardArgs)
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(LuaJIT DEFAULT_MSG LUAJIT_LIBRARY LUAJIT_INCLUDE_DIR)
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(LuaJIT DEFAULT_MSG LUAJIT_LIBRARY LUAJIT_INCLUDE_DIR)

+ 0 - 147
CMake/Modules/FindPkgMacros.cmake

@@ -1,147 +0,0 @@
-##################################################################
-# Provides some common functionality for the FindPackage modules
-##################################################################
-
-# Begin processing of package
-macro(findpkg_begin PREFIX)
-  if (NOT ${PREFIX}_FIND_QUIETLY)
-    message(STATUS "Looking for ${PREFIX}...")
-  endif ()
-endmacro(findpkg_begin)
-
-# Display a status message unless FIND_QUIETLY is set
-macro(pkg_message PREFIX)
-  if (NOT ${PREFIX}_FIND_QUIETLY)
-    message(STATUS ${ARGN})
-  endif ()
-endmacro(pkg_message)
-
-# Get environment variable, define it as ENV_$var and make sure backslashes are converted to forward slashes
-macro(getenv_path VAR)
-   set(ENV_${VAR} $ENV{${VAR}})
-   # replace won't work if var is blank
-   if (ENV_${VAR})
-     string( REGEX REPLACE "\\\\" "/" ENV_${VAR} ${ENV_${VAR}} )
-   endif ()
-endmacro(getenv_path)
-
-# Construct search paths for includes and libraries from a PREFIX_PATH
-macro(create_search_paths PREFIX)
-  foreach(dir ${${PREFIX}_PREFIX_PATH})
-    set(${PREFIX}_INC_SEARCH_PATH ${${PREFIX}_INC_SEARCH_PATH}
-      ${dir}/include ${dir}/Include ${dir}/include/${PREFIX} ${dir}/Headers)
-    set(${PREFIX}_LIB_SEARCH_PATH ${${PREFIX}_LIB_SEARCH_PATH}
-      ${dir}/lib ${dir}/Lib ${dir}/lib/${PREFIX} ${dir}/Libs)
-    set(${PREFIX}_BIN_SEARCH_PATH ${${PREFIX}_BIN_SEARCH_PATH}
-      ${dir}/bin)
-  endforeach(dir)
-  set(${PREFIX}_FRAMEWORK_SEARCH_PATH ${${PREFIX}_PREFIX_PATH})
-endmacro(create_search_paths)
-
-# clear cache variables if a certain variable changed
-macro(clear_if_changed TESTVAR)
-  # test against internal check variable
-  # HACK: Apparently, adding a variable to the cache cleans up the list
-  # a bit. We need to also remove any empty strings from the list, but
-  # at the same time ensure that we are actually dealing with a list.
-  list(APPEND ${TESTVAR} "")
-  list(REMOVE_ITEM ${TESTVAR} "")
-  if (NOT "${${TESTVAR}}" STREQUAL "${${TESTVAR}_INT_CHECK}")
-    message(STATUS "${TESTVAR} changed.")
-    foreach(var ${ARGN})
-      set(${var} "NOTFOUND" CACHE STRING "x" FORCE)
-    endforeach(var)
-  endif ()
-  set(${TESTVAR}_INT_CHECK ${${TESTVAR}} CACHE INTERNAL "x" FORCE)
-endmacro(clear_if_changed)
-
-# Try to get some hints from pkg-config, if available
-macro(use_pkgconfig PREFIX PKGNAME)
-  find_package(PkgConfig)
-  if (PKG_CONFIG_FOUND)
-    pkg_check_modules(${PREFIX} ${PKGNAME})
-  endif ()
-endmacro (use_pkgconfig)
-
-# Couple a set of release AND debug libraries (or frameworks)
-macro(make_library_set PREFIX)
-  if (${PREFIX}_FWK)
-    set(${PREFIX} ${${PREFIX}_FWK})
-  elseif (${PREFIX}_REL AND ${PREFIX}_DBG)
-    set(${PREFIX} optimized ${${PREFIX}_REL} debug ${${PREFIX}_DBG})
-  elseif (${PREFIX}_REL)
-    set(${PREFIX} ${${PREFIX}_REL})
-  elseif (${PREFIX}_DBG)
-    set(${PREFIX} ${${PREFIX}_DBG})
-  endif ()
-endmacro(make_library_set)
-
-# Generate debug names from given release names
-macro(get_debug_names PREFIX)
-  foreach(i ${${PREFIX}})
-    set(${PREFIX}_DBG ${${PREFIX}_DBG} ${i}d ${i}D ${i}_d ${i}_D ${i}_debug ${i})
-  endforeach(i)
-endmacro(get_debug_names)
-
-# Add the parent dir from DIR to VAR 
-macro(add_parent_dir VAR DIR)
-  get_filename_component(${DIR}_TEMP "${${DIR}}/.." ABSOLUTE)
-  set(${VAR} ${${VAR}} ${${DIR}_TEMP})
-endmacro(add_parent_dir)
-
-# Do the final processing for the package find.
-macro(findpkg_finish PREFIX)
-  # skip if already processed during this run
-  if (NOT ${PREFIX}_FOUND)
-    if (${PREFIX}_INCLUDE_DIR AND ${PREFIX}_LIBRARY)
-      set(${PREFIX}_FOUND TRUE)
-      set(${PREFIX}_INCLUDE_DIRS ${${PREFIX}_INCLUDE_DIR})
-      set(${PREFIX}_LIBRARIES ${${PREFIX}_LIBRARY})
-      if (NOT ${PREFIX}_FIND_QUIETLY)
-        message(STATUS "Found ${PREFIX}: ${${PREFIX}_LIBRARIES}")
-      endif ()
-    else ()
-      if (NOT ${PREFIX}_FIND_QUIETLY)
-        message(STATUS "Could not locate ${PREFIX}")
-      endif ()
-      if (${PREFIX}_FIND_REQUIRED)
-        message(FATAL_ERROR "Required library ${PREFIX} not found! Install the library (including dev packages) and try again. If the library is already installed, set the missing variables manually in cmake.")
-      endif ()
-    endif ()
-
-    mark_as_advanced(${PREFIX}_INCLUDE_DIR ${PREFIX}_LIBRARY ${PREFIX}_LIBRARY_REL ${PREFIX}_LIBRARY_DBG ${PREFIX}_LIBRARY_FWK)
-  endif ()
-endmacro(findpkg_finish)
-
-
-# Slightly customised framework finder
-MACRO(findpkg_framework fwk)
-  IF(APPLE)
-    SET(${fwk}_FRAMEWORK_PATH
-      ${${fwk}_FRAMEWORK_SEARCH_PATH}
-      ${CMAKE_FRAMEWORK_PATH}
-      ~/Library/Frameworks
-      /Library/Frameworks
-      /System/Library/Frameworks
-      /Network/Library/Frameworks
-      /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk/System/Library/Frameworks/
-      ${CMAKE_CURRENT_SOURCE_DIR}/lib/Release
-      ${CMAKE_CURRENT_SOURCE_DIR}/lib/Debug
-      ${OGRE_PREFIX_PATH}/lib/Release
-      ${OGRE_PREFIX_PATH}/lib/Debug
-      ${OGRE_PREFIX_BUILD}/lib/Release
-      ${OGRE_PREFIX_BUILD}/lib/Debug
-    )
-    FOREACH(dir ${${fwk}_FRAMEWORK_PATH})
-      SET(fwkpath ${dir}/${fwk}.framework)
-      IF(EXISTS ${fwkpath})
-        SET(${fwk}_FRAMEWORK_INCLUDES ${${fwk}_FRAMEWORK_INCLUDES}
-          ${fwkpath}/Headers ${fwkpath}/PrivateHeaders)
-        SET(${fwk}_FRAMEWORK_PATH ${dir})
-        if (NOT ${fwk}_LIBRARY_FWK)
-          SET(${fwk}_LIBRARY_FWK "-framework ${fwk}")
-        endif ()
-      ENDIF(EXISTS ${fwkpath})
-    ENDFOREACH(dir)
-  ENDIF(APPLE)
-ENDMACRO(findpkg_framework)

+ 0 - 191
CMake/Modules/FindSDL2.cmake

@@ -1,191 +0,0 @@
-# Locate SDL2 library
-# This module defines
-# SDL2_LIBRARY, the name of the library to link against
-# SDL2_FOUND, if false, do not try to link to SDL2
-# SDL2_INCLUDE_DIR, where to find SDL.h
-#
-# Source: https://code.google.com/p/freerct/source/browse/trunk/CMake/FindSDL2.cmake
-#
-# This module responds to the the flag:
-# SDL2_BUILDING_LIBRARY
-# If this is defined, then no SDL2main will be linked in because
-# only applications need main().
-# Otherwise, it is assumed you are building an application and this
-# module will attempt to locate and set the the proper link flags
-# as part of the returned SDL2_LIBRARY variable.
-#
-# Don't forget to include SDLmain.h and SDLmain.m your project for the
-# OS X framework based version. (Other versions link to -lSDL2main which
-# this module will try to find on your behalf.) Also for OS X, this
-# module will automatically add the -framework Cocoa on your behalf.
-#
-#
-# Additional Note: If you see an empty SDL2_LIBRARY_TEMP in your configuration
-# and no SDL2_LIBRARY, it means CMake did not find your SDL2 library
-# (SDL2.dll, libsdl2.so, SDL2.framework, etc).
-# Set SDL2_LIBRARY_TEMP to point to your SDL2 library, and configure again.
-# Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this value
-# as appropriate. These values are used to generate the final SDL2_LIBRARY
-# variable, but when these values are unset, SDL2_LIBRARY does not get created.
-#
-#
-# $SDL2DIR is an environment variable that would
-# correspond to the ./configure --prefix=$SDL2DIR
-# used in building SDL2.
-# l.e.galup  9-20-02
-#
-# Modified by Eric Wing.
-# Added code to assist with automated building by using environmental variables
-# and providing a more controlled/consistent search behavior.
-# Added new modifications to recognize OS X frameworks and
-# additional Unix paths (FreeBSD, etc).
-# Also corrected the header search path to follow "proper" SDL guidelines.
-# Added a search for SDL2main which is needed by some platforms.
-# Added a search for threads which is needed by some platforms.
-# Added needed compile switches for MinGW.
-#
-# On OSX, this will prefer the Framework version (if found) over others.
-# People will have to manually change the cache values of
-# SDL2_LIBRARY to override this selection or set the CMake environment
-# CMAKE_INCLUDE_PATH to modify the search paths.
-#
-# Note that the header path has changed from SDL2/SDL.h to just SDL.h
-# This needed to change because "proper" SDL convention
-# is #include "SDL.h", not <SDL2/SDL.h>. This is done for portability
-# reasons because not all systems place things in SDL2/ (see FreeBSD).
-
-#=============================================================================
-# Copyright 2003-2009 Kitware, Inc.
-#
-# Distributed under the OSI-approved BSD License (the "License");
-# see accompanying file Copyright.txt for details.
-#
-# This software is distributed WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the License for more information.
-#=============================================================================
-# (To distribute this file outside of CMake, substitute the full
-#  License text for the above reference.)
-
-# Look for the library in config mode first.
-find_package(SDL2 CONFIG)
-if(SDL2_FOUND AND TARGET SDL2::SDL2)
-  message(STATUS "Found SDL2 in config mode, version ${SDL2_VERSION}.")
-  set(SDL2_LIBRARY "SDL2::SDL2")
-  return()
-else()
-  message(STATUS "Looking for SDL2 in module mode.")
-endif()
-
-SET(SDL2_SEARCH_PATHS
-  ~/Library/Frameworks
-  /Library/Frameworks
-  /usr/local
-  /usr
-  /sw # Fink
-  /opt/local # DarwinPorts
-  /opt/csw # Blastwave
-  /opt
-)
-
-FIND_PATH(SDL2_INCLUDE_DIR SDL.h
-  HINTS
-  $ENV{SDL2DIR}
-  PATH_SUFFIXES include/SDL2 include
-  PATHS ${SDL2_SEARCH_PATHS}
-)
-
-FIND_LIBRARY(SDL2_LIBRARY_TEMP
-  NAMES SDL2
-  HINTS
-  $ENV{SDL2DIR}
-  PATH_SUFFIXES lib64 lib
-  PATHS ${SDL2_SEARCH_PATHS}
-)
-
-IF(NOT SDL2_BUILDING_LIBRARY)
-  IF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework")
-    # Non-OS X framework versions expect you to also dynamically link to
-    # SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms
-    # seem to provide SDL2main for compatibility even though they don't
-    # necessarily need it.
-    FIND_LIBRARY(SDL2MAIN_LIBRARY
-      NAMES SDL2main
-      HINTS
-      $ENV{SDL2DIR}
-      PATH_SUFFIXES lib64 lib
-      PATHS ${SDL2_SEARCH_PATHS}
-    )
-  ENDIF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework")
-ENDIF(NOT SDL2_BUILDING_LIBRARY)
-
-# SDL2 may require threads on your system.
-# The Apple build may not need an explicit flag because one of the
-# frameworks may already provide it.
-# But for non-OSX systems, I will use the CMake Threads package.
-IF(NOT APPLE)
-  FIND_PACKAGE(Threads)
-ENDIF(NOT APPLE)
-
-# MinGW needs an additional library, mwindows
-# It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -lmwindows
-# (Actually on second look, I think it only needs one of the m* libraries.)
-IF(MINGW)
-  SET(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW")
-ENDIF(MINGW)
-
-IF(SDL2_LIBRARY_TEMP)
-  # For SDL2main
-  IF(NOT SDL2_BUILDING_LIBRARY)
-    IF(SDL2MAIN_LIBRARY)
-      SET(SDL2_LIBRARY_TEMP ${SDL2MAIN_LIBRARY} ${SDL2_LIBRARY_TEMP})
-    ENDIF(SDL2MAIN_LIBRARY)
-  ENDIF(NOT SDL2_BUILDING_LIBRARY)
-
-  # For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa.
-  # CMake doesn't display the -framework Cocoa string in the UI even
-  # though it actually is there if I modify a pre-used variable.
-  # I think it has something to do with the CACHE STRING.
-  # So I use a temporary variable until the end so I can set the
-  # "real" variable in one-shot.
-  IF(APPLE)
-    SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} "-framework Cocoa")
-  ENDIF(APPLE)
-
-  # For threads, as mentioned Apple doesn't need this.
-  # In fact, there seems to be a problem if I used the Threads package
-  # and try using this line, so I'm just skipping it entirely for OS X.
-  IF(NOT APPLE)
-    SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT})
-  ENDIF(NOT APPLE)
-
-  # For MinGW library
-  IF(MINGW)
-    SET(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP})
-  ENDIF(MINGW)
-
-  # Set the final string here so the GUI reflects the final state.
-  SET(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL2 Library can be found")
-  # Set the temp variable to INTERNAL so it is not seen in the CMake GUI
-  SET(SDL2_LIBRARY_TEMP "${SDL2_LIBRARY_TEMP}" CACHE INTERNAL "")
-ENDIF(SDL2_LIBRARY_TEMP)
-
-if(SDL2_INCLUDE_DIR AND EXISTS "${SDL2_INCLUDE_DIR}/SDL_version.h")
-  file(STRINGS "${SDL2_INCLUDE_DIR}/SDL_version.h" SDL2_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_MAJOR_VERSION[ \t]+[0-9]+$")
-  file(STRINGS "${SDL2_INCLUDE_DIR}/SDL_version.h" SDL2_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_MINOR_VERSION[ \t]+[0-9]+$")
-  file(STRINGS "${SDL2_INCLUDE_DIR}/SDL_version.h" SDL2_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_PATCHLEVEL[ \t]+[0-9]+$")
-  string(REGEX REPLACE "^#define[ \t]+SDL_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_VERSION_MAJOR "${SDL2_VERSION_MAJOR_LINE}")
-  string(REGEX REPLACE "^#define[ \t]+SDL_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_VERSION_MINOR "${SDL2_VERSION_MINOR_LINE}")
-  string(REGEX REPLACE "^#define[ \t]+SDL_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_VERSION_PATCH "${SDL2_VERSION_PATCH_LINE}")
-  set(SDL2_VERSION ${SDL2_VERSION_MAJOR}.${SDL2_VERSION_MINOR}.${SDL2_VERSION_PATCH})
-  unset(SDL2_VERSION_MAJOR_LINE)
-  unset(SDL2_VERSION_MINOR_LINE)
-  unset(SDL2_VERSION_PATCH_LINE)
-  unset(SDL2_VERSION_MAJOR)
-  unset(SDL2_VERSION_MINOR)
-  unset(SDL2_VERSION_PATCH)
-endif()
-
-INCLUDE(FindPackageHandleStandardArgs)
-
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR VERSION_VAR SDL2_VERSION)

+ 48 - 112
CMake/Modules/FindSDL2_image.cmake

@@ -1,119 +1,55 @@
-# Locate SDL2_image library
-# This module defines
-# SDL2_IMAGE_LIBRARY, the name of the library to link against
-# SDL2_IMAGE_FOUND, if false, do not try to link to SDL2_image
-# SDL2_IMAGE_INCLUDE_DIR, where to find SDL.h
-#
-# Source: https://code.google.com/p/freerct/source/browse/trunk/CMake/FindSDL2_ttf.cmake
-#
-# $SDL2_IMAGE_DIR is an environment variable that would
-# correspond to the ./configure --prefix=$SDL2_IMAGE_DIR
-# used in building SDL2_image.
-# l.e.galup  9-20-02
-#
-# Modified by Eric Wing.
-# Added code to assist with automated building by using environmental variables
-# and providing a more controlled/consistent search behavior.
-# Added new modifications to recognize OS X frameworks and
-# additional Unix paths (FreeBSD, etc).
-# Also corrected the header search path to follow "proper" SDL guidelines.
-# Added a search for SDL2main which is needed by some platforms.
-# Added a search for threads which is needed by some platforms.
-# Added needed compile switches for MinGW.
-#
-# On OSX, this will prefer the Framework version (if found) over others.
-# People will have to manually change the cache values of
-# SDL2_LIBRARY to override this selection or set the CMake environment
-# CMAKE_INCLUDE_PATH to modify the search paths.
-#
-# Note that the header path has changed from SDL2/SDL.h to just SDL.h
-# This needed to change because "proper" SDL convention
-# is #include "SDL.h", not <SDL2/SDL.h>. This is done for portability
-# reasons because not all systems place things in SDL2/ (see FreeBSD).
-
-#=============================================================================
-# Copyright 2003-2009 Kitware, Inc.
-#
-# Distributed under the OSI-approved BSD License (the "License");
-# see accompanying file Copyright.txt for details.
-#
-# This software is distributed WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the License for more information.
-#=============================================================================
-# (To distribute this file outside of CMake, substitute the full
-#  License text for the above reference.)
-
-SET(SDL2_IMAGE_SEARCH_PATHS
-        ~/Library/Frameworks
-        /Library/Frameworks
-        /usr/local
-        /usr
-        /sw # Fink
-        /opt/local # DarwinPorts
-        /opt/csw # Blastwave
-        /opt
+#[[
+	Find module for SDL_image version 2 that matches the naming convention of the SDL2_imageConfig.cmake file
+	provided in official distributions of the SDL2_image library.
+
+	This is necessary on some distributions, including Ubuntu 20.04 and 22.04, because the libsdl2-image-dev package
+	doesn't provide the config file. https://packages.ubuntu.com/focal/amd64/libsdl2-image-dev/filelist
+	Furthermore, the CMake integrated find module is only compatible with the SDL1_image.
+
+	Defines the imported CMake target:
+		SDL2_image::SDL2_image
+
+	In addition, the following CMake variables are defined according to normal conventions:
+		SDL2_IMAGE_LIBRARIES
+		SDL2_IMAGE_INCLUDE_DIRS
+		SDL2_IMAGE_FOUND
+]]
+
+# Prefer config mode.
+find_package(SDL2_image CONFIG QUIET)
+if(TARGET SDL2_image::SDL2_image)
+	return()
+endif()
+
+# Not found in config mode, proceed as a normal find module.
+find_path(SDL2_IMAGE_INCLUDE_DIR SDL_image.h
+	HINTS ENV SDL2_IMAGE_DIR
+	PATH_SUFFIXES SDL2
 )
 )
 
 
-FIND_PATH(SDL2_IMAGE_INCLUDE_DIR SDL_image.h
-        HINTS
-        $ENV{SDL2_IMAGE_DIR}
-        PATH_SUFFIXES include/SDL2 include
-        PATHS ${SDL2_IMAGE_SEARCH_PATHS}
+find_library(SDL2_IMAGE_LIBRARY
+	NAMES SDL2_image
+	HINTS ENV SDL2_IMAGE_DIR
+	PATH_SUFFIXES lib
 )
 )
 
 
-FIND_LIBRARY(SDL2_IMAGE_LIBRARY_TEMP
-        NAMES SDL2_image
-        HINTS
-        $ENV{SDL2_IMAGE_DIR}
-        PATH_SUFFIXES lib64 lib
-        PATHS ${SDL2_IMAGE_SEARCH_PATHS}
-)
-
-# SDL2_image may require threads on your system.
-# The Apple build may not need an explicit flag because one of the
-# frameworks may already provide it.
-# But for non-OSX systems, I will use the CMake Threads package.
-# IF(NOT APPLE)
-        # FIND_PACKAGE(Threads)
-# ENDIF(NOT APPLE)
-
-# MinGW needs an additional library, mwindows
-# It's total link flags should look like -lmingw32 -lSDL2_image -lmwindows
-# (Actually on second look, I think it only needs one of the m* libraries.)
-IF(MINGW)
-        SET(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW")
-ENDIF(MINGW)
+set(SDL2_IMAGE_INCLUDE_DIRS ${SDL2_IMAGE_INCLUDE_DIR})
+set(SDL2_IMAGE_LIBRARIES ${SDL2_IMAGE_LIBRARY})
 
 
-IF(SDL2_IMAGE_LIBRARY_TEMP)
-        # For OS X, SDL2_IMAGE uses Cocoa as a backend so it must link to Cocoa.
-        # CMake doesn't display the -framework Cocoa string in the UI even
-        # though it actually is there if I modify a pre-used variable.
-        # I think it has something to do with the CACHE STRING.
-        # So I use a temporary variable until the end so I can set the
-        # "real" variable in one-shot.
-        # IF(APPLE)
-                # SET(SDL2_IMAGE_LIBRARY_TEMP ${SDL2_IMAGE_LIBRARY_TEMP} "-framework Cocoa")
-        # ENDIF(APPLE)
+include(FindPackageHandleStandardArgs)
 
 
-        # For threads, as mentioned Apple doesn't need this.
-        # In fact, there seems to be a problem if I used the Threads package
-        # and try using this line, so I'm just skipping it entirely for OS X.
-        # IF(NOT APPLE)
-                # SET(SDL2_IMAGE_LIBRARY_TEMP ${SDL2_IMAGE_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT})
-        # ENDIF(NOT APPLE)
-
-        # For MinGW library
-        # IF(MINGW)
-                # SET(SDL2_IMAGE_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_IMAGE_LIBRARY_TEMP})
-        # ENDIF(MINGW)
-
-        # Set the final string here so the GUI reflects the final state.
-        SET(SDL2_IMAGE_LIBRARY ${SDL2_IMAGE_LIBRARY_TEMP} CACHE STRING "Where the SDL2_IMAGE Library can be found")
-        # Set the temp variable to INTERNAL so it is not seen in the CMake GUI
-        SET(SDL2_IMAGE_LIBRARY_TEMP "${SDL2_IMAGE_LIBRARY_TEMP}" CACHE INTERNAL "")
-ENDIF(SDL2_IMAGE_LIBRARY_TEMP)
-
-INCLUDE(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(SDL2_image
+	REQUIRED_VARS SDL2_IMAGE_LIBRARIES SDL2_IMAGE_INCLUDE_DIRS
+)
 
 
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2_image REQUIRED_VARS SDL2_IMAGE_LIBRARY SDL2_IMAGE_INCLUDE_DIR)
+mark_as_advanced(SDL2_IMAGE_LIBRARY SDL2_IMAGE_INCLUDE_DIR)
+
+if(SDL2_IMAGE_FOUND)
+	if(NOT TARGET SDL2_image::SDL2_image)
+		add_library(SDL2_image::SDL2_image INTERFACE IMPORTED)
+		set_target_properties(SDL2_image::SDL2_image PROPERTIES
+			INTERFACE_INCLUDE_DIRECTORIES "${SDL2_IMAGE_INCLUDE_DIRS}"
+			INTERFACE_LINK_LIBRARIES "${SDL2_IMAGE_LIBRARIES}"
+		)
+	endif()
+endif()

+ 0 - 209
CMake/Modules/FindSFML.cmake

@@ -1,209 +0,0 @@
-# This script locates the SFML library
-# ------------------------------------
-#
-# Usage
-# -----
-#
-# When you try to locate the SFML libraries, you must specify which modules you want to use (system, window, graphics, network, audio, main).
-# If none is given, the SFML_LIBRARIES variable will be empty and you'll end up linking to nothing.
-# example:
-#   find_package(SFML COMPONENTS graphics window system) // find the graphics, window and system modules
-#
-# You can enforce a specific version, either MAJOR.MINOR or only MAJOR.
-# If nothing is specified, the version won't be checked (ie. any version will be accepted).
-# example:
-#   find_package(SFML COMPONENTS ...)     // no specific version required
-#   find_package(SFML 2 COMPONENTS ...)   // any 2.x version
-#   find_package(SFML 2.4 COMPONENTS ...) // version 2.4 or greater
-#
-# By default, the dynamic libraries of SFML will be found. To find the static ones instead,
-# you must set the SFML_STATIC_LIBRARIES variable to TRUE before calling find_package(SFML ...).
-# In case of static linking, the SFML_STATIC macro will also be defined by this script.
-# example:
-#   set(SFML_STATIC_LIBRARIES TRUE)
-#   find_package(SFML 2 COMPONENTS network system)
-#
-# On Mac OS X if SFML_STATIC_LIBRARIES is not set to TRUE then by default CMake will search for frameworks unless
-# CMAKE_FIND_FRAMEWORK is set to "NEVER" for example. Please refer to CMake documentation for more details.
-# Moreover, keep in mind that SFML frameworks are only available as release libraries unlike dylibs which
-# are available for both release and debug modes.
-#
-# If SFML is not installed in a standard path, you can use the SFML_ROOT CMake (or environment) variable
-# to tell CMake where SFML is.
-#
-# Output
-# ------
-#
-# This script defines the following variables:
-# - For each specified module XXX (system, window, graphics, network, audio, main):
-#   - SFML_XXX_LIBRARY_DEBUG:   the name of the debug library of the xxx module (set to SFML_XXX_LIBRARY_RELEASE is no debug version is found)
-#   - SFML_XXX_LIBRARY_RELEASE: the name of the release library of the xxx module (set to SFML_XXX_LIBRARY_DEBUG is no release version is found)
-#   - SFML_XXX_LIBRARY:         the name of the library to link to for the xxx module (includes both debug and optimized names if necessary)
-#   - SFML_XXX_FOUND:           true if either the debug or release library of the xxx module is found
-# - SFML_LIBRARIES:   the list of all libraries corresponding to the required modules
-# - SFML_FOUND:       true if all the required modules are found
-# - SFML_INCLUDE_DIR: the path where SFML headers are located (the directory containing the SFML/Config.hpp file)
-#
-# example:
-#   find_package(SFML 2 COMPONENTS system window graphics audio REQUIRED)
-#   include_directories(${SFML_INCLUDE_DIR})
-#   add_executable(myapp ...)
-#   target_link_libraries(myapp ${SFML_LIBRARIES})
-
-# define the SFML_STATIC macro if static build was chosen
-if(SFML_STATIC_LIBRARIES)
-    add_definitions(-DSFML_STATIC)
-endif()
-
-# deduce the libraries suffix from the options
-set(FIND_SFML_LIB_SUFFIX "")
-if(SFML_STATIC_LIBRARIES)
-    set(FIND_SFML_LIB_SUFFIX "${FIND_SFML_LIB_SUFFIX}-s")
-endif()
-
-# find the SFML include directory
-find_path(SFML_INCLUDE_DIR SFML/Config.hpp
-          PATH_SUFFIXES include
-          PATHS
-          ${SFML_ROOT}
-          $ENV{SFML_ROOT}
-          ~/Library/Frameworks
-          /Library/Frameworks
-          /usr/local/
-          /usr/
-          /sw          # Fink
-          /opt/local/  # DarwinPorts
-          /opt/csw/    # Blastwave
-          /opt/)
-
-# check the version number
-set(SFML_VERSION_OK TRUE)
-if(SFML_FIND_VERSION AND SFML_INCLUDE_DIR)
-    # extract the major and minor version numbers from SFML/Config.hpp
-    # we have to handle framework a little bit differently :
-    if("${SFML_INCLUDE_DIR}" MATCHES "SFML.framework")
-        set(SFML_CONFIG_HPP_INPUT "${SFML_INCLUDE_DIR}/Headers/Config.hpp")
-    else()
-        set(SFML_CONFIG_HPP_INPUT "${SFML_INCLUDE_DIR}/SFML/Config.hpp")
-    endif()
-    FILE(READ "${SFML_CONFIG_HPP_INPUT}" SFML_CONFIG_HPP_CONTENTS)
-    STRING(REGEX MATCH ".*#define SFML_VERSION_MAJOR ([0-9]+).*#define SFML_VERSION_MINOR ([0-9]+).*" SFML_CONFIG_HPP_CONTENTS "${SFML_CONFIG_HPP_CONTENTS}")
-    STRING(REGEX REPLACE ".*#define SFML_VERSION_MAJOR ([0-9]+).*" "\\1" SFML_VERSION_MAJOR "${SFML_CONFIG_HPP_CONTENTS}")
-    STRING(REGEX REPLACE ".*#define SFML_VERSION_MINOR ([0-9]+).*" "\\1" SFML_VERSION_MINOR "${SFML_CONFIG_HPP_CONTENTS}")
-    math(EXPR SFML_REQUESTED_VERSION "${SFML_FIND_VERSION_MAJOR} * 10 + ${SFML_FIND_VERSION_MINOR}")
-
-    # if we could extract them, compare with the requested version number
-    if (SFML_VERSION_MAJOR)
-        # transform version numbers to an integer
-        math(EXPR SFML_VERSION "${SFML_VERSION_MAJOR} * 10 + ${SFML_VERSION_MINOR}")
-
-        # compare them
-        if(SFML_VERSION LESS SFML_REQUESTED_VERSION)
-            set(SFML_VERSION_OK FALSE)
-        endif()
-    else()
-        # SFML version is < 2.0
-        if (SFML_REQUESTED_VERSION GREATER 19)
-            set(SFML_VERSION_OK FALSE)
-            set(SFML_VERSION_MAJOR 1)
-            set(SFML_VERSION_MINOR x)
-        endif()
-    endif()
-endif()
-
-# find the requested modules
-set(SFML_FOUND TRUE) # will be set to false if one of the required modules is not found
-set(FIND_SFML_LIB_PATHS
-    ${SFML_ROOT}
-    $ENV{SFML_ROOT}
-    ~/Library/Frameworks
-    /Library/Frameworks
-    /usr/local
-    /usr
-    /sw
-    /opt/local
-    /opt/csw
-    /opt)
-foreach(FIND_SFML_COMPONENT ${SFML_FIND_COMPONENTS})
-    string(TOLOWER ${FIND_SFML_COMPONENT} FIND_SFML_COMPONENT_LOWER)
-    string(TOUPPER ${FIND_SFML_COMPONENT} FIND_SFML_COMPONENT_UPPER)
-    set(FIND_SFML_COMPONENT_NAME sfml-${FIND_SFML_COMPONENT_LOWER}${FIND_SFML_LIB_SUFFIX})
-
-    # no suffix for sfml-main, it is always a static library
-    if(FIND_SFML_COMPONENT_LOWER STREQUAL "main")
-        set(FIND_SFML_COMPONENT_NAME sfml-${FIND_SFML_COMPONENT_LOWER})
-    endif()
-
-    # debug library
-    find_library(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG
-                 NAMES ${FIND_SFML_COMPONENT_NAME}-d
-                 PATH_SUFFIXES lib64 lib
-                 PATHS ${FIND_SFML_LIB_PATHS})
-
-    # release library
-    find_library(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE
-                 NAMES ${FIND_SFML_COMPONENT_NAME}
-                 PATH_SUFFIXES lib64 lib
-                 PATHS ${FIND_SFML_LIB_PATHS})
-
-    if (SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG OR SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE)
-        # library found
-        set(SFML_${FIND_SFML_COMPONENT_UPPER}_FOUND TRUE)
-        
-        # if both are found, set SFML_XXX_LIBRARY to contain both
-        if (SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG AND SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE)
-            set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY debug     ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG}
-                                                          optimized ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE})
-        endif()
-
-        # if only one debug/release variant is found, set the other to be equal to the found one
-        if (SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG AND NOT SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE)
-            # debug and not release
-            set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG})
-            set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY         ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG})
-        endif()
-        if (SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE AND NOT SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG)
-            # release and not debug
-            set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE})
-            set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY       ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE})
-        endif()
-    else()
-        # library not found
-        set(SFML_FOUND FALSE)
-        set(SFML_${FIND_SFML_COMPONENT_UPPER}_FOUND FALSE)
-        set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY "")
-        set(FIND_SFML_MISSING "${FIND_SFML_MISSING} SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY")
-    endif()
-
-    # mark as advanced
-    MARK_AS_ADVANCED(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY
-                     SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE
-                     SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG)
-
-    # add to the global list of libraries
-    set(SFML_LIBRARIES ${SFML_LIBRARIES} "${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY}")
-endforeach()
-
-# handle errors
-if(NOT SFML_VERSION_OK)
-    # SFML version not ok
-    set(FIND_SFML_ERROR "SFML found but version too low (requested: ${SFML_FIND_VERSION}, found: ${SFML_VERSION_MAJOR}.${SFML_VERSION_MINOR})")
-    set(SFML_FOUND FALSE)
-elseif(NOT SFML_FOUND)
-    # include directory or library not found
-    set(FIND_SFML_ERROR "Could NOT find SFML (missing: ${FIND_SFML_MISSING})")
-endif()
-if (NOT SFML_FOUND)
-    if(SFML_FIND_REQUIRED)
-        # fatal error
-        message(FATAL_ERROR ${FIND_SFML_ERROR})
-    elseif(NOT SFML_FIND_QUIETLY)
-        # error but continue
-        message("${FIND_SFML_ERROR}")
-    endif()
-endif()
-
-# handle success
-if(SFML_FOUND)
-    message(STATUS "Found SFML ${SFML_VERSION_MAJOR}.${SFML_VERSION_MINOR} in ${SFML_INCLUDE_DIR}")
-endif()

+ 64 - 18
CMake/Modules/Findlunasvg.cmake

@@ -1,32 +1,78 @@
-# Try to find LunaSVG
-if (TARGET lunasvg)
-	# This is for when lunasvg is added via an add_subdirectory
-	get_target_property(LUNASVG_LIBRARY lunasvg LIBRARY_OUTPUT_NAME)
-	get_target_property(LUNASVG_INCLUDE_DIR lunasvg INCLUDE_DIRECTORIES)
+#[[
+	Custom find module for lunasvg, will use existing target if available.
+
+	Input variables:
+		LUNASVG_INCLUDE_DIR
+		LUNASVG_LIBRARY_DEBUG
+		LUNASVG_LIBRARY_RELEASE
+
+	Output variables:
+		lunasvg_FOUND
+		lunasvg_VERSION
+
+	Resulting targets:
+		lunasvg::lunasvg
+]]
+
+include(FindPackageHandleStandardArgs)
+
+if(NOT TARGET lunasvg::lunasvg)
+	# Look for vcpkg port
+	find_package("unofficial-lunasvg" CONFIG QUIET)
+	if(TARGET unofficial::lunasvg::lunasvg)
+		add_library(lunasvg::lunasvg ALIAS unofficial::lunasvg::lunasvg)
+	endif()
+endif()
+
+if(TARGET lunasvg::lunasvg)
+	# Since the target already exists, we declare it as found
+	set(lunasvg_FOUND TRUE)
+	if(NOT DEFINED lunasvg_VERSION)
+		set(lunasvg_VERSION "UNKNOWN")
+	endif()
+elseif(TARGET lunasvg)
+	# This is for when lunasvg is added via add_subdirectory
+	add_library(lunasvg::lunasvg ALIAS lunasvg)
+	set(lunasvg_FOUND TRUE)
+	if(NOT DEFINED lunasvg_VERSION)
+		set(lunasvg_VERSION "UNKNOWN")
+	endif()
 else()
 else()
+	# Search for the library using input variables
 	find_path(LUNASVG_INCLUDE_DIR lunasvg.h
 	find_path(LUNASVG_INCLUDE_DIR lunasvg.h
-			HINTS $ENV{LUNASVG_DIR}
-			PATH_SUFFIXES lunasvg lunasvg/include include )
+		HINTS $ENV{LUNASVG_DIR}
+		PATH_SUFFIXES lunasvg lunasvg/include include)
 
 
 	find_library(LUNASVG_LIBRARY_DEBUG NAMES lunasvg liblunasvg
 	find_library(LUNASVG_LIBRARY_DEBUG NAMES lunasvg liblunasvg
-				HINTS $ENV{LUNASVG_DIR} $ENV{LUNASVG_DIR}/build
-				PATH_SUFFIXES debug Debug)
-				
+		HINTS $ENV{LUNASVG_DIR} $ENV{LUNASVG_DIR}/build
+		PATH_SUFFIXES debug Debug)
+
 	find_library(LUNASVG_LIBRARY_RELEASE NAMES lunasvg liblunasvg
 	find_library(LUNASVG_LIBRARY_RELEASE NAMES lunasvg liblunasvg
-				HINTS $ENV{LUNASVG_DIR} $ENV{LUNASVG_DIR}/build
-				PATH_SUFFIXES release Release)
+		HINTS $ENV{LUNASVG_DIR} $ENV{LUNASVG_DIR}/build
+		PATH_SUFFIXES release Release)
 
 
 	set(LUNASVG_LIBRARY
 	set(LUNASVG_LIBRARY
 		debug ${LUNASVG_LIBRARY_DEBUG}
 		debug ${LUNASVG_LIBRARY_DEBUG}
 		optimized ${LUNASVG_LIBRARY_RELEASE}
 		optimized ${LUNASVG_LIBRARY_RELEASE}
 	)
 	)
 
 
-	include(FindPackageHandleStandardArgs)
-	find_package_handle_standard_args(lunasvg  DEFAULT_MSG
-									LUNASVG_LIBRARY LUNASVG_INCLUDE_DIR)
+	find_package_handle_standard_args(lunasvg DEFAULT_MSG
+		LUNASVG_LIBRARY LUNASVG_INCLUDE_DIR)
+
+	mark_as_advanced(LUNASVG_INCLUDE_DIR LUNASVG_LIBRARY_DEBUG LUNASVG_LIBRARY_RELEASE)
+
+	set(LUNASVG_LIBRARIES ${LUNASVG_LIBRARY})
+	set(LUNASVG_INCLUDE_DIRS ${LUNASVG_INCLUDE_DIR})
+
+	if(lunasvg_FOUND)
+		add_library(lunasvg::lunasvg INTERFACE IMPORTED)
+		set(lunasvg_VERSION "UNKNOWN")
 
 
-	mark_as_advanced(LUNASVG_INCLUDE_DIR LUNASVG_LIBRARY_DEBUG LUNASVG_LIBRARY_RELEASE )
+		target_include_directories(lunasvg::lunasvg INTERFACE ${LUNASVG_INCLUDE_DIRS})
+		target_link_libraries(lunasvg::lunasvg INTERFACE ${LUNASVG_LIBRARIES})
+	endif()
 
 
-	set(LUNASVG_LIBRARIES ${LUNASVG_LIBRARY} )
-	set(LUNASVG_INCLUDE_DIRS ${LUNASVG_INCLUDE_DIR} )
+	if(NOT DEFINED lunasvg_VERSION)
+		set(lunasvg_VERSION "UNKNOWN")
+	endif()
 endif()
 endif()

+ 32 - 0
CMake/OptionsLists.cmake

@@ -0,0 +1,32 @@
+#[[
+	Lists of options available to configure certain aspects of the project.
+]]
+
+set(RMLUI_BACKEND_OPTIONS
+	"auto"
+	"native"
+	"Win32_GL2"
+	"Win32_VK"
+	"X11_GL2"
+	"SDL_GL2"
+	"SDL_GL3"
+	"SDL_VK"
+	"SDL_SDLrenderer"
+	"SFML_GL2"
+	"GLFW_GL2"
+	"GLFW_GL3"
+	"GLFW_VK"
+	"BackwardCompatible_GLFW_GL2"
+	"BackwardCompatible_GLFW_GL3"
+)
+
+set(RMLUI_FONT_ENGINE_OPTIONS
+	"none"
+	"freetype"
+)
+
+set(RMLUI_LUA_BINDINGS_LIBRARY_OPTIONS
+	"lua"
+	"lua_as_cxx"
+	"luajit"
+)

+ 85 - 0
CMake/PackageUtilities.cmake

@@ -0,0 +1,85 @@
+#[[
+	Utility functions used for packaging RmlUi.
+]]
+
+#[[
+	Install all license files, including for all installed packages in vcpkg if in use.
+]]
+function(install_licenses)
+	set(bin_licenses_dir "${CMAKE_CURRENT_BINARY_DIR}/Licenses")
+	configure_file("${PROJECT_SOURCE_DIR}/LICENSE.txt"
+		"${bin_licenses_dir}/LICENSE.txt" COPYONLY
+	)
+	configure_file("${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Containers/LICENSE.txt"
+		"${bin_licenses_dir}/LICENSE.Core.ThirdParty.txt" COPYONLY
+	)
+	configure_file("${PROJECT_SOURCE_DIR}/Source/Debugger/LICENSE.txt"
+		"${bin_licenses_dir}/LICENSE.Debugger.ThirdParty.txt" COPYONLY
+	)
+
+	if(VCPKG_TOOLCHAIN)
+		set(vcpkg_share_dir "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/share")
+		file(GLOB copyright_files "${vcpkg_share_dir}/*/copyright")
+		foreach(copyright_file IN LISTS copyright_files)
+			get_filename_component(name ${copyright_file} DIRECTORY)
+			get_filename_component(name ${name} NAME)
+			if(NOT "${name}" MATCHES "^vcpkg-")
+				set(copy_destination "${bin_licenses_dir}/Dependencies/${name}.txt")
+				configure_file(${copyright_file} ${copy_destination} COPYONLY)
+			endif()
+		endforeach()
+	endif()
+
+	install(DIRECTORY "${bin_licenses_dir}/" DESTINATION "${CMAKE_INSTALL_DATADIR}")
+endfunction()
+
+#[[
+	Install a text file with build info.
+]]
+function(install_build_info)
+	if(NOT RMLUI_ARCHITECTURE OR NOT RMLUI_COMMIT_DATE OR NOT RMLUI_RUN_ID OR NOT RMLUI_SHA)
+		message(FATAL_ERROR "Cannot install build info: Missing variables")
+	endif()
+	generate_rmlui_version_string()
+	file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/Build.txt"
+		"RmlUi ${RMLUI_VERSION_SHORT} binaries for ${RMLUI_ARCHITECTURE}.\n\n"
+		"https://github.com/mikke89/RmlUi\n\n"
+		"Built using ${CMAKE_GENERATOR} (${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}) on ${RMLUI_COMMIT_DATE} (run ${RMLUI_RUN_ID}).\n"
+		"Commit id: ${RMLUI_SHA}"
+	)
+	install(FILES "${CMAKE_CURRENT_BINARY_DIR}/Build.txt"
+		DESTINATION "${CMAKE_INSTALL_DATADIR}"
+	)
+endfunction()
+
+#[[
+	Install all dependencies found for the current vcpkg target triplet.
+]]
+function(install_vcpkg_dependencies)
+	if(NOT VCPKG_TOOLCHAIN)
+		message(FATAL_ERROR "Cannot install vcpkg dependencies: vcpkg not in use")
+	endif()
+	set(vcpkg_triplet_dir "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}")
+	set(common_patterns
+		PATTERN "${VCPKG_TARGET_TRIPLET}/tools" EXCLUDE
+		PATTERN "pkgconfig" EXCLUDE
+		PATTERN "vcpkg*" EXCLUDE
+		PATTERN "*.pdb" EXCLUDE
+	)
+	message(STATUS "Installing vcpkg dependencies from: ${vcpkg_triplet_dir}")
+	install(DIRECTORY "${vcpkg_triplet_dir}/"
+		DESTINATION "${RMLUI_INSTALL_DEPENDENCIES_DIR}"
+		CONFIGURATIONS "Release"
+		${common_patterns}
+		PATTERN "debug" EXCLUDE
+		PATTERN "*debug.cmake" EXCLUDE
+	)
+	install(DIRECTORY "${vcpkg_triplet_dir}/"
+		DESTINATION "${RMLUI_INSTALL_DEPENDENCIES_DIR}"
+		CONFIGURATIONS "Debug"
+		${common_patterns}
+		PATTERN "${VCPKG_TARGET_TRIPLET}/bin" EXCLUDE
+		PATTERN "${VCPKG_TARGET_TRIPLET}/lib" EXCLUDE
+		PATTERN "*release.cmake" EXCLUDE
+	)
+endfunction()

+ 0 - 190
CMake/Platform/iOS.cmake

@@ -1,190 +0,0 @@
-# This file is based off of the Platform/Darwin.cmake and Platform/UnixPaths.cmake
-# files which are included with CMake 2.8.4
-# It has been altered for iOS development
-
-# Options:
-#
-# IOS_PLATFORM = OS (default) or SIMULATOR
-#   This decides if SDKS will be selected from the iPhoneOS.platform or iPhoneSimulator.platform folders
-#   OS - the default, used to build for iPhone and iPad physical devices, which have an arm arch.
-#   SIMULATOR - used to build for the Simulator platforms, which have an x86 arch.
-#
-# CMAKE_IOS_DEVELOPER_ROOT = automatic(default) or /path/to/platform/Developer folder
-#   By default this location is automatcially chosen based on the IOS_PLATFORM value above.
-#   If set manually, it will override the default location and force the user of a particular Developer Platform
-#
-# CMAKE_IOS_SDK_ROOT = automatic(default) or /path/to/platform/Developer/SDKs/SDK folder
-#   By default this location is automatcially chosen based on the CMAKE_IOS_DEVELOPER_ROOT value.
-#   In this case it will always be the most up-to-date SDK found in the CMAKE_IOS_DEVELOPER_ROOT path.
-#   If set manually, this will force the use of a specific SDK version
-
-# Macros:
-#
-# set_xcode_property (TARGET XCODE_PROPERTY XCODE_VALUE)
-#  A convenience macro for setting xcode specific properties on targets
-#  example: set_xcode_property (myioslib IPHONEOS_DEPLOYMENT_TARGET "3.1")
-#
-# find_host_package (PROGRAM ARGS)
-#  A macro used to find executable programs on the host system, not within the iOS environment.
-#  Thanks to the android-cmake project for providing the command
-
-
-# Standard settings
-set (CMAKE_SYSTEM_NAME Darwin)
-set (CMAKE_SYSTEM_VERSION 1)
-set (UNIX True)
-set (APPLE True)
-set (IOS True)
-
-# Required as of cmake 2.8.10
-set (CMAKE_OSX_DEPLOYMENT_TARGET "" CACHE STRING "Force unset of the deployment target for iOS" FORCE)
-
-# Determine the cmake host system version so we know where to find the iOS SDKs
-find_program (CMAKE_UNAME uname /bin /usr/bin /usr/local/bin)
-if (CMAKE_UNAME)
-	exec_program(uname ARGS -r OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_VERSION)
-	string (REGEX REPLACE "^([0-9]+)\\.([0-9]+).*$" "\\1" DARWIN_MAJOR_VERSION "${CMAKE_HOST_SYSTEM_VERSION}")
-endif (CMAKE_UNAME)
-
-# Skip the platform compiler checks for cross compiling
-set (CMAKE_CXX_COMPILER_WORKS TRUE)
-set (CMAKE_C_COMPILER_WORKS TRUE)
-
-# All iOS/Darwin specific settings - some may be redundant
-set (CMAKE_SHARED_LIBRARY_PREFIX "lib")
-set (CMAKE_SHARED_LIBRARY_SUFFIX ".dylib")
-set (CMAKE_SHARED_MODULE_PREFIX "lib")
-set (CMAKE_SHARED_MODULE_SUFFIX ".so")
-set (CMAKE_MODULE_EXISTS 1)
-set (CMAKE_DL_LIBS "")
-
-set (CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG "-compatibility_version ")
-set (CMAKE_C_OSX_CURRENT_VERSION_FLAG "-current_version ")
-set (CMAKE_CXX_OSX_COMPATIBILITY_VERSION_FLAG "${CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG}")
-set (CMAKE_CXX_OSX_CURRENT_VERSION_FLAG "${CMAKE_C_OSX_CURRENT_VERSION_FLAG}")
-
-# Hidden visibilty is required for cxx on iOS 
-set (CMAKE_C_FLAGS_INIT "")
-set (CMAKE_CXX_FLAGS_INIT "-fvisibility=hidden -fvisibility-inlines-hidden")
-
-set (CMAKE_C_LINK_FLAGS "-Wl,-search_paths_first ${CMAKE_C_LINK_FLAGS}")
-set (CMAKE_CXX_LINK_FLAGS "-Wl,-search_paths_first ${CMAKE_CXX_LINK_FLAGS}")
-
-set (CMAKE_PLATFORM_HAS_INSTALLNAME 1)
-set (CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-dynamiclib -headerpad_max_install_names")
-set (CMAKE_SHARED_MODULE_CREATE_C_FLAGS "-bundle -headerpad_max_install_names")
-set (CMAKE_SHARED_MODULE_LOADER_C_FLAG "-Wl,-bundle_loader,")
-set (CMAKE_SHARED_MODULE_LOADER_CXX_FLAG "-Wl,-bundle_loader,")
-set (CMAKE_FIND_LIBRARY_SUFFIXES ".dylib" ".so" ".a")
-
-# hack: if a new cmake (which uses CMAKE_INSTALL_NAME_TOOL) runs on an old build tree
-# (where install_name_tool was hardcoded) and where CMAKE_INSTALL_NAME_TOOL isn't in the cache
-# and still cmake didn't fail in CMakeFindBinUtils.cmake (because it isn't rerun)
-# hardcode CMAKE_INSTALL_NAME_TOOL here to install_name_tool, so it behaves as it did before, Alex
-if (NOT DEFINED CMAKE_INSTALL_NAME_TOOL)
-	find_program(CMAKE_INSTALL_NAME_TOOL install_name_tool)
-endif (NOT DEFINED CMAKE_INSTALL_NAME_TOOL)
-
-# Setup iOS platform unless specified manually with IOS_PLATFORM
-if (NOT DEFINED IOS_PLATFORM)
-	set (IOS_PLATFORM "OS")
-endif (NOT DEFINED IOS_PLATFORM)
-set (IOS_PLATFORM ${IOS_PLATFORM} CACHE STRING "Type of iOS Platform")
-
-# Check the platform selection and setup for developer root
-if (${IOS_PLATFORM} STREQUAL "OS")
-	set (IOS_PLATFORM_LOCATION "iPhoneOS.platform")
-
-	# This causes the installers to properly locate the output libraries
-	set (CMAKE_XCODE_EFFECTIVE_PLATFORMS "-iphoneos")
-elseif (${IOS_PLATFORM} STREQUAL "SIMULATOR")
-	set (IOS_PLATFORM_LOCATION "iPhoneSimulator.platform")
-
-	# This causes the installers to properly locate the output libraries
-	set (CMAKE_XCODE_EFFECTIVE_PLATFORMS "-iphonesimulator")
-else (${IOS_PLATFORM} STREQUAL "OS")
-	message (FATAL_ERROR "Unsupported IOS_PLATFORM value selected. Please choose OS or SIMULATOR")
-endif (${IOS_PLATFORM} STREQUAL "OS")
-
-# Setup iOS developer location unless specified manually with CMAKE_IOS_DEVELOPER_ROOT
-# Note Xcode 4.3 changed the installation location, choose the most recent one available
-set (XCODE_POST_43_ROOT "/Applications/Xcode.app/Contents/Developer/Platforms/${IOS_PLATFORM_LOCATION}/Developer")
-set (XCODE_PRE_43_ROOT "/Developer/Platforms/${IOS_PLATFORM_LOCATION}/Developer")
-if (NOT DEFINED CMAKE_IOS_DEVELOPER_ROOT)
-	if (EXISTS ${XCODE_POST_43_ROOT})
-		set (CMAKE_IOS_DEVELOPER_ROOT ${XCODE_POST_43_ROOT})
-	elseif(EXISTS ${XCODE_PRE_43_ROOT})
-		set (CMAKE_IOS_DEVELOPER_ROOT ${XCODE_PRE_43_ROOT})
-	endif (EXISTS ${XCODE_POST_43_ROOT})
-endif (NOT DEFINED CMAKE_IOS_DEVELOPER_ROOT)
-set (CMAKE_IOS_DEVELOPER_ROOT ${CMAKE_IOS_DEVELOPER_ROOT} CACHE PATH "Location of iOS Platform")
-
-# Find and use the most recent iOS sdk unless specified manually with CMAKE_IOS_SDK_ROOT
-if (NOT DEFINED CMAKE_IOS_SDK_ROOT)
-	file (GLOB _CMAKE_IOS_SDKS "${CMAKE_IOS_DEVELOPER_ROOT}/SDKs/*")
-	if (_CMAKE_IOS_SDKS) 
-		list (SORT _CMAKE_IOS_SDKS)
-		list (REVERSE _CMAKE_IOS_SDKS)
-		list (GET _CMAKE_IOS_SDKS 0 CMAKE_IOS_SDK_ROOT)
-	else (_CMAKE_IOS_SDKS)
-		message (FATAL_ERROR "No iOS SDK's found in default search path ${CMAKE_IOS_DEVELOPER_ROOT}. Manually set CMAKE_IOS_SDK_ROOT or install the iOS SDK.")
-	endif (_CMAKE_IOS_SDKS)
-	message (STATUS "Toolchain using default iOS SDK: ${CMAKE_IOS_SDK_ROOT}")
-endif (NOT DEFINED CMAKE_IOS_SDK_ROOT)
-set (CMAKE_IOS_SDK_ROOT ${CMAKE_IOS_SDK_ROOT} CACHE PATH "Location of the selected iOS SDK")
-
-# Set the sysroot default to the most recent SDK
-set (CMAKE_OSX_SYSROOT ${CMAKE_IOS_SDK_ROOT} CACHE PATH "Sysroot used for iOS support")
-
-# set the architecture for iOS 
-# NOTE: Currently both ARCHS_STANDARD_32_BIT and ARCHS_UNIVERSAL_IPHONE_OS set armv7 only, so set both manually
-if (${IOS_PLATFORM} STREQUAL "OS")
-	set (IOS_ARCH armv6 armv7 armv7s arm64)
-else (${IOS_PLATFORM} STREQUAL "OS")
-	set (IOS_ARCH i386 x86_64)
-endif (${IOS_PLATFORM} STREQUAL "OS")
-
-if (NOT DEFINED CMAKE_OSX_ARCHITECTURES)
-	set (CMAKE_OSX_ARCHITECTURES ${IOS_ARCH} CACHE string  "Build architecture for iOS")
-endif (NOT DEFINED CMAKE_OSX_ARCHITECTURES)
-
-# Set the find root to the iOS developer roots and to user defined paths
-set (CMAKE_FIND_ROOT_PATH ${CMAKE_IOS_DEVELOPER_ROOT} ${CMAKE_IOS_SDK_ROOT} ${CMAKE_PREFIX_PATH} CACHE string  "iOS find search path root")
-
-# default to searching for frameworks first
-set (CMAKE_FIND_FRAMEWORK FIRST)
-
-# set up the default search directories for frameworks
-set (CMAKE_SYSTEM_FRAMEWORK_PATH
-	${CMAKE_IOS_SDK_ROOT}/System/Library/Frameworks
-	${CMAKE_IOS_SDK_ROOT}/System/Library/PrivateFrameworks
-	${CMAKE_IOS_SDK_ROOT}/Developer/Library/Frameworks
-)
-
-# only search the iOS sdks, not the remainder of the host filesystem
-set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY)
-set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
-set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
-
-
-# This little macro lets you set any XCode specific property
-macro (set_xcode_property TARGET XCODE_PROPERTY XCODE_VALUE)
-	set_property (TARGET ${TARGET} PROPERTY XCODE_ATTRIBUTE_${XCODE_PROPERTY} ${XCODE_VALUE})
-endmacro (set_xcode_property)
-
-
-# This macro lets you find executable programs on the host system
-macro (find_host_package)
-	set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
-	set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER)
-	set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER)
-	set (IOS FALSE)
-
-	find_package(${ARGN})
-
-	set (IOS TRUE)
-	set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY)
-	set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
-	set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
-endmacro (find_host_package)
-

+ 0 - 11
CMake/RmlUiConfig.cmake.build.in

@@ -1,11 +0,0 @@
-@PACKAGE_INIT@
-
-set_and_check(RmlUi_INCLUDE_DIRS "@PACKAGE_INCLUDE_DIR@")
-set(RmlUi_LIBRARIES @RMLUI_EXPORTED_TARGETS@)
-list(GET RmlUi_LIBRARIES 0 RMLUI_FIRST_TARGET)
-
-if(NOT (TARGET ${RMLUI_FIRST_TARGET}))
-  include("${CMAKE_CURRENT_LIST_DIR}/RmlUiTargets.cmake")
-endif()
-
-check_required_components(RmlUi)

+ 34 - 0
CMake/RmlUiConfig.cmake.in

@@ -0,0 +1,34 @@
+set(RMLUI_IS_CONFIG_FILE TRUE)
+set(RMLUI_SVG_PLUGIN @RMLUI_SVG_PLUGIN@)
+set(RMLUI_LOTTIE_PLUGIN @RMLUI_LOTTIE_PLUGIN@)
+set(RMLUI_FONT_ENGINE "@RMLUI_FONT_ENGINE@")
+set(RMLUI_LUA_BINDINGS @RMLUI_LUA_BINDINGS@)
+set(RMLUI_LUA_BINDINGS_LIBRARY "@RMLUI_LUA_BINDINGS_LIBRARY@")
+set(RMLUI_TRACY_PROFILING "@RMLUI_TRACY_PROFILING@")
+
+macro(report_dependency_not_found friendly_name target_name)
+	if(RmlUi_FIND_REQUIRED)
+		message(FATAL_ERROR
+				"${friendly_name} could not be found.\n"
+				"Please ensure that ${friendly_name} can be found by CMake, or linked to using \"${target_name}\" as its "
+				"target name. If you are consuming RmlUi from another CMake project, you can create an ALIAS target to "
+				"offer an alternative name for a CMake target."
+			)
+	endif()
+	return()
+endmacro()
+macro(report_dependency_found_or_error friendly_name target_name)
+	if(NOT TARGET ${target_name})
+		report_dependency_not_found(${friendly_name} ${target_name})
+	endif()
+	if(ARGC GREATER "2" AND ARGV2)
+		set(success_message " - ${ARGV2}")
+	endif()
+	message(STATUS "Found ${friendly_name} target ${target_name}${success_message}")
+endmacro()
+
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/Modules")
+
+include("${CMAKE_CURRENT_LIST_DIR}/Dependencies.cmake")
+
+include("${CMAKE_CURRENT_LIST_DIR}/RmlUiTargets.cmake")

+ 0 - 7
CMake/RmlUiConfig.cmake.install.in

@@ -1,7 +0,0 @@
-@PACKAGE_INIT@
-
-set_and_check(RmlUi_INCLUDE_DIRS "@PACKAGE_INCLUDE_INSTALL_DIR@")
-set(RmlUi_LIBRARIES @RMLUI_EXPORTED_TARGETS@)
-include("${CMAKE_CURRENT_LIST_DIR}/RmlUiTargets.cmake")
-
-check_required_components(RmlUi)

+ 46 - 0
CMake/RuntimeUtilities.cmake

@@ -0,0 +1,46 @@
+#[[
+	Utility functions used to set the output of runtime executables and dependencies.
+]]
+
+#[[
+	Change the runtime output directory of all targets declared in this scope. This is particularly helpful on Windows
+	when building the project as a shared library, so that all DLLs are located together with any built executables. The
+	set() call is guarded against pre-definitions in order to respect consumer choice.
+]]
+function(setup_runtime_output_directory)
+	if(NOT DEFINED CMAKE_RUNTIME_OUTPUT_DIRECTORY)
+		set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" PARENT_SCOPE)
+	endif()
+endfunction()
+
+# RMLUI_CMAKE_MINIMUM_VERSION_RAISE_NOTICE:
+# From CMake 3.21 there is no need for the following function, as we can set the RUNTIME_DEPENDENCY_SET on
+# install(TARGETS) directly.
+#[[
+	Output variable to conditionally set up runtime dependency arguments when installing targets.
+	This feature is only available from CMake 3.21, on older version this feature will be disabled.
+	Output variable:
+		- RMLUI_RUNTIME_DEPENDENCY_SET_ARG: Argument to use for the install(TARGETS) command.
+]]
+function(setup_runtime_dependency_set_arg)
+	set(RMLUI_RUNTIME_DEPENDENCY_SET_ARG "" PARENT_SCOPE)
+	if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.21")
+		set(RMLUI_RUNTIME_DEPENDENCY_SET_ARG RUNTIME_DEPENDENCY_SET rmlui_runtime_dependencies PARENT_SCOPE)
+	endif()
+endfunction()
+
+#[[
+	Install runtime dependencies on supported platforms, when enabled by the user.
+]]
+function(install_runtime_dependencies)
+	if(WIN32 AND RMLUI_RUNTIME_DEPENDENCY_SET_ARG)
+		option(RMLUI_INSTALL_RUNTIME_DEPENDENCIES "Include runtime dependencies when installing RmlUi." ON)
+		mark_as_advanced(RMLUI_INSTALL_RUNTIME_DEPENDENCIES)
+		if(RMLUI_INSTALL_RUNTIME_DEPENDENCIES)
+			install(RUNTIME_DEPENDENCY_SET rmlui_runtime_dependencies
+				PRE_EXCLUDE_REGEXES "api-ms-" "ext-ms-"
+				POST_EXCLUDE_REGEXES ".*system32/.*\\.dll"
+			)
+		endif()
+	endif()
+endfunction()

+ 0 - 234
CMake/SampleFileList.cmake

@@ -1,234 +0,0 @@
-# This file was auto-generated with gen_samplelists.sh
-
-set(shell_HDR_FILES
-    ${PROJECT_SOURCE_DIR}/Samples/shell/include/PlatformExtensions.h
-    ${PROJECT_SOURCE_DIR}/Samples/shell/include/RendererExtensions.h
-    ${PROJECT_SOURCE_DIR}/Samples/shell/include/Shell.h
-    ${PROJECT_SOURCE_DIR}/Samples/shell/include/ShellFileInterface.h
-)
-
-set(shell_SRC_FILES
-    ${PROJECT_SOURCE_DIR}/Samples/shell/src/PlatformExtensions.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/shell/src/RendererExtensions.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/shell/src/Shell.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/shell/src/ShellFileInterface.cpp
-)
-
-set(animation_HDR_FILES
-)
-
-set(animation_SRC_FILES
-    ${PROJECT_SOURCE_DIR}/Samples/basic/animation/src/main.cpp
-)
-
-set(benchmark_HDR_FILES
-)
-
-set(benchmark_SRC_FILES
-    ${PROJECT_SOURCE_DIR}/Samples/basic/benchmark/src/main.cpp
-)
-
-set(bitmapfont_HDR_FILES
-    ${PROJECT_SOURCE_DIR}/Samples/basic/bitmapfont/src/FontEngineBitmap.h
-    ${PROJECT_SOURCE_DIR}/Samples/basic/bitmapfont/src/FontEngineInterfaceBitmap.h
-)
-
-set(bitmapfont_SRC_FILES
-    ${PROJECT_SOURCE_DIR}/Samples/basic/bitmapfont/src/FontEngineBitmap.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/basic/bitmapfont/src/FontEngineInterfaceBitmap.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/basic/bitmapfont/src/main.cpp
-)
-
-set(customlog_HDR_FILES
-    ${PROJECT_SOURCE_DIR}/Samples/basic/customlog/src/SystemInterface.h
-)
-
-set(customlog_SRC_FILES
-    ${PROJECT_SOURCE_DIR}/Samples/basic/customlog/src/main.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/basic/customlog/src/SystemInterface.cpp
-)
-
-set(databinding_HDR_FILES
-)
-
-set(databinding_SRC_FILES
-    ${PROJECT_SOURCE_DIR}/Samples/basic/databinding/src/main.cpp
-)
-
-set(demo_HDR_FILES
-)
-
-set(demo_SRC_FILES
-    ${PROJECT_SOURCE_DIR}/Samples/basic/demo/src/main.cpp
-)
-
-set(drag_HDR_FILES
-    ${PROJECT_SOURCE_DIR}/Samples/basic/drag/src/DragListener.h
-    ${PROJECT_SOURCE_DIR}/Samples/basic/drag/src/Inventory.h
-)
-
-set(drag_SRC_FILES
-    ${PROJECT_SOURCE_DIR}/Samples/basic/drag/src/DragListener.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/basic/drag/src/Inventory.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/basic/drag/src/main.cpp
-)
-
-set(effects_HDR_FILES
-)
-
-set(effects_SRC_FILES
-    ${PROJECT_SOURCE_DIR}/Samples/basic/effects/src/main.cpp
-)
-
-set(loaddocument_HDR_FILES
-)
-
-set(loaddocument_SRC_FILES
-    ${PROJECT_SOURCE_DIR}/Samples/basic/loaddocument/src/main.cpp
-)
-
-set(treeview_HDR_FILES
-    ${PROJECT_SOURCE_DIR}/Samples/basic/treeview/src/FileBrowser.h
-)
-
-set(treeview_SRC_FILES
-    ${PROJECT_SOURCE_DIR}/Samples/basic/treeview/src/FileBrowser.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/basic/treeview/src/main.cpp
-)
-
-set(transform_HDR_FILES
-)
-
-set(transform_SRC_FILES
-    ${PROJECT_SOURCE_DIR}/Samples/basic/transform/src/main.cpp
-)
-
-set(harfbuzzshaping_HDR_FILES
-    ${PROJECT_SOURCE_DIR}/Samples/basic/harfbuzzshaping/src/FontEngineInterfaceHarfBuzz.h
-    ${PROJECT_SOURCE_DIR}/Samples/basic/harfbuzzshaping/src/FontFace.h
-    ${PROJECT_SOURCE_DIR}/Samples/basic/harfbuzzshaping/src/FontFaceHandleHarfBuzz.h
-    ${PROJECT_SOURCE_DIR}/Samples/basic/harfbuzzshaping/src/FontFaceLayer.h
-    ${PROJECT_SOURCE_DIR}/Samples/basic/harfbuzzshaping/src/FontFamily.h
-    ${PROJECT_SOURCE_DIR}/Samples/basic/harfbuzzshaping/src/FontGlyph.h
-    ${PROJECT_SOURCE_DIR}/Samples/basic/harfbuzzshaping/src/FontProvider.h
-    ${PROJECT_SOURCE_DIR}/Samples/basic/harfbuzzshaping/src/FreeTypeInterface.h
-    ${PROJECT_SOURCE_DIR}/Samples/basic/harfbuzzshaping/src/LanguageData.h
-)
-
-set(harfbuzzshaping_SRC_FILES
-    ${PROJECT_SOURCE_DIR}/Samples/basic/harfbuzzshaping/src/FontEngineInterfaceHarfBuzz.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/basic/harfbuzzshaping/src/FontFace.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/basic/harfbuzzshaping/src/FontFaceHandleHarfBuzz.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/basic/harfbuzzshaping/src/FontFaceLayer.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/basic/harfbuzzshaping/src/FontFamily.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/basic/harfbuzzshaping/src/FontProvider.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/basic/harfbuzzshaping/src/FreeTypeInterface.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/basic/harfbuzzshaping/src/main.cpp
-)
-
-set(lottie_HDR_FILES
-)
-
-set(lottie_SRC_FILES
-    ${PROJECT_SOURCE_DIR}/Samples/basic/lottie/src/main.cpp
-)
-
-set(svg_HDR_FILES
-)
-
-set(svg_SRC_FILES
-    ${PROJECT_SOURCE_DIR}/Samples/basic/svg/src/main.cpp
-)
-
-set(tutorial_template_HDR_FILES
-)
-
-set(tutorial_template_SRC_FILES
-    ${PROJECT_SOURCE_DIR}/Samples/tutorial/template/src/main.cpp
-)
-
-set(tutorial_drag_HDR_FILES
-    ${PROJECT_SOURCE_DIR}/Samples/tutorial/drag/src/Inventory.h
-)
-
-set(tutorial_drag_SRC_FILES
-    ${PROJECT_SOURCE_DIR}/Samples/tutorial/drag/src/Inventory.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/tutorial/drag/src/main.cpp
-)
-
-set(invaders_HDR_FILES
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/DecoratorDefender.h
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/DecoratorStarfield.h
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/Defender.h
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/ElementGame.h
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/EventHandler.h
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/EventHandlerHighScore.h
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/EventHandlerOptions.h
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/EventHandlerStartGame.h
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/EventListener.h
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/EventListenerInstancer.h
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/EventManager.h
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/Game.h
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/GameDetails.h
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/HighScores.h
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/Invader.h
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/Mothership.h
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/Shield.h
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/Sprite.h
-)
-
-set(invaders_SRC_FILES
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/DecoratorDefender.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/DecoratorStarfield.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/Defender.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/ElementGame.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/EventHandler.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/EventHandlerHighScore.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/EventHandlerOptions.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/EventHandlerStartGame.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/EventListener.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/EventListenerInstancer.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/EventManager.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/Game.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/GameDetails.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/HighScores.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/Invader.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/main.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/Mothership.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/Shield.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/invaders/src/Sprite.cpp
-)
-
-set(luainvaders_HDR_FILES
-    ${PROJECT_SOURCE_DIR}/Samples/luainvaders/src/DecoratorDefender.h
-    ${PROJECT_SOURCE_DIR}/Samples/luainvaders/src/DecoratorStarfield.h
-    ${PROJECT_SOURCE_DIR}/Samples/luainvaders/src/Defender.h
-    ${PROJECT_SOURCE_DIR}/Samples/luainvaders/src/ElementGame.h
-    ${PROJECT_SOURCE_DIR}/Samples/luainvaders/src/ElementGameInstancer.h
-    ${PROJECT_SOURCE_DIR}/Samples/luainvaders/src/Game.h
-    ${PROJECT_SOURCE_DIR}/Samples/luainvaders/src/GameDetails.h
-    ${PROJECT_SOURCE_DIR}/Samples/luainvaders/src/HighScores.h
-    ${PROJECT_SOURCE_DIR}/Samples/luainvaders/src/Invader.h
-    ${PROJECT_SOURCE_DIR}/Samples/luainvaders/src/LuaInterface.h
-    ${PROJECT_SOURCE_DIR}/Samples/luainvaders/src/Mothership.h
-    ${PROJECT_SOURCE_DIR}/Samples/luainvaders/src/Shield.h
-    ${PROJECT_SOURCE_DIR}/Samples/luainvaders/src/Sprite.h
-)
-
-set(luainvaders_SRC_FILES
-    ${PROJECT_SOURCE_DIR}/Samples/luainvaders/src/DecoratorDefender.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/luainvaders/src/DecoratorStarfield.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/luainvaders/src/Defender.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/luainvaders/src/ElementGame.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/luainvaders/src/ElementGameInstancer.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/luainvaders/src/Game.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/luainvaders/src/GameDetails.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/luainvaders/src/HighScores.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/luainvaders/src/Invader.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/luainvaders/src/LuaInterface.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/luainvaders/src/main.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/luainvaders/src/Mothership.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/luainvaders/src/Shield.cpp
-    ${PROJECT_SOURCE_DIR}/Samples/luainvaders/src/Sprite.cpp
-)
-

+ 192 - 0
CMake/Utilities.cmake

@@ -0,0 +1,192 @@
+#[[
+	Various global utility functions for RmlUi.
+]]
+
+#[[
+	Format the RmlUi version as it should normally be displayed.
+	Output:
+		RMLUI_VERSION_SHORT: The RmlUi version as a string
+]]
+function(generate_rmlui_version_string)
+	if(NOT RMLUI_VERSION_RELEASE)
+		set(RMLUI_VERSION_SUFFIX "-dev")
+	endif()
+	if(PROJECT_VERSION_PATCH GREATER 0)
+		set(RMLUI_VERSION_PATCH ".${PROJECT_VERSION_PATCH}")
+	endif()
+	set(RMLUI_VERSION_SHORT
+		"${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}${RMLUI_VERSION_PATCH}${RMLUI_VERSION_SUFFIX}"
+		PARENT_SCOPE
+	)
+endfunction()
+
+#[[
+	Stop execution and print an error message for the dependency.
+	Arguments:
+		- friendly_name: Friendly name of the target
+		- target_name: Name of the CMake target the project will link against
+]]
+function(report_dependency_not_found friendly_name target_name)
+	message(FATAL_ERROR
+		"${friendly_name} could not be found.\n"
+		"Please ensure that ${friendly_name} can be found by CMake, or linked to using \"${target_name}\" as its "
+		"target name. If you are consuming RmlUi from another CMake project, you can create an ALIAS target to "
+		"offer an alternative name for a CMake target."
+	)
+endfunction()
+
+#[[
+	Verify that the target is found and print a message, otherwise stop execution.
+	Arguments:
+		- friendly_name: Friendly name of the target
+		- target_name: Name of the CMake target the project will link against
+		- success_message: Message to show when the target exists (optional)
+]]
+function(report_dependency_found_or_error friendly_name target_name)
+	if(NOT TARGET ${target_name})
+		report_dependency_not_found(${friendly_name} ${target_name})
+	endif()
+	if(ARGC GREATER "2" AND ARGV2)
+		set(success_message " - ${ARGV2}")
+	endif()
+	message(STATUS "Found ${target_name}${success_message}")
+endfunction()
+
+#[[
+	Set compiler options and features that are common to all RmlUi targets.
+	Arguments:
+		- target: The name of the target to set
+]]
+function(set_common_target_options target)
+	target_compile_features(${target} PUBLIC cxx_std_14)
+	set_target_properties(${target} PROPERTIES C_EXTENSIONS OFF CXX_EXTENSIONS OFF)
+
+	if(RMLUI_COMPILER_OPTIONS)
+		if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
+			target_compile_options(${target} PRIVATE -Wall -Wextra -pedantic)
+		elseif(MSVC)
+			target_compile_options(${target} PRIVATE /W4 /w44062 /permissive-)
+			target_compile_definitions(${target} PRIVATE _CRT_SECURE_NO_WARNINGS)
+			if(CMAKE_GENERATOR MATCHES "Visual Studio")
+				target_compile_options(${target} PRIVATE /MP)
+			endif()
+		endif()
+	endif()
+
+	if(RMLUI_WARNINGS_AS_ERRORS)
+		if(NOT RMLUI_COMPILER_OPTIONS)
+			message(FATAL_ERROR "Option RMLUI_WARNINGS_AS_ERRORS requires RMLUI_COMPILER_OPTIONS=ON.")
+		endif()
+
+		if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
+			target_compile_options(${target} PRIVATE -Werror)
+		elseif(MSVC)
+			target_compile_options(${target} PRIVATE /WX)
+		else()
+			message(FATAL_ERROR "Unknown compiler, cannot enable option RMLUI_WARNINGS_AS_ERRORS.")
+		endif()
+	endif()
+endfunction()
+
+#[[
+	Create installation rule for MSVC program database (PDB) files.
+	Arguments:
+		- target: The name of the target
+]]
+function(install_target_pdb target)
+	if(MSVC)
+		if(BUILD_SHARED_LIBS)
+			# The following only works for linker-generated PDBs, not compiler-generated PDBs produced in static builds.
+			install(FILES "$<TARGET_PDB_FILE:${target}>"
+				DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+				OPTIONAL
+			)
+		else()
+			get_property(output_name TARGET ${target} PROPERTY OUTPUT_NAME)
+			install(FILES "$<TARGET_FILE_DIR:${target}>/${output_name}.pdb"
+				DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+				OPTIONAL
+			)
+		endif()
+	endif()
+endfunction()
+
+#[[
+	Create installation rules for sample targets.
+	Arguments:
+		- target: The name of the target
+]]
+function(install_sample_target target)
+	set(data_dirs "")
+	foreach(dir IN ITEMS "data" "lua")
+		if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${dir}")
+			list(APPEND data_dirs "${dir}")
+		endif()
+	endforeach()
+	file(RELATIVE_PATH sample_path ${PROJECT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
+	install(TARGETS ${TARGET_NAME}
+		${RMLUI_RUNTIME_DEPENDENCY_SET_ARG}
+		RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+	)
+	set(install_dirs "src" ${data_dirs})
+	install(DIRECTORY ${install_dirs}
+		DESTINATION "${CMAKE_INSTALL_DATADIR}/${sample_path}"
+	)
+
+	# Set Emscripten-specific sample properties and assets.
+	if(EMSCRIPTEN)
+		# Make Emscripten generate the default HTML shell for the sample.
+		set_property(TARGET ${target} PROPERTY SUFFIX ".html")
+
+		# Enables Asyncify which we only need since the backend doesn't control the main loop. This enables us to yield
+		# to the browser during the backend call to Backend::ProcessEvents(). Asyncify results in larger and slower
+		# code, users are instead encouraged to use 'emscripten_set_main_loop()' and family.
+		target_link_libraries(${target} PRIVATE "-sASYNCIFY")
+
+		# We don't know the needed memory beforehand, allow it to grow.
+		target_link_libraries(${target} PRIVATE "-sALLOW_MEMORY_GROWTH")
+
+		# Add common assets.
+		set(common_assets_dir "Samples/assets")
+		target_link_libraries(${target} PRIVATE "--preload-file ${PROJECT_SOURCE_DIR}/${common_assets_dir}/@/${common_assets_dir}/")
+		file(GLOB asset_files "${PROJECT_SOURCE_DIR}/${common_assets_dir}/*")
+
+		# Add sample-specific assets.
+		foreach(source_relative_dir IN LISTS data_dirs)
+			set(abs_dir "${CMAKE_CURRENT_SOURCE_DIR}/${source_relative_dir}")
+			file(RELATIVE_PATH root_relative_dir "${PROJECT_SOURCE_DIR}" "${abs_dir}")
+			target_link_libraries(${target} PRIVATE "--preload-file ${abs_dir}/@/${root_relative_dir}/")
+			file(GLOB sample_data_files "${abs_dir}/*")
+			list(APPEND asset_files "${sample_data_files}")
+		endforeach()
+
+		# Add a linker dependency to all asset files, so that the linker runs again if any asset is modified.
+		set_target_properties(${target} PROPERTIES LINK_DEPENDS "${asset_files}")
+	endif()
+endfunction()
+
+#[[
+	Enable or disable a given configuration type for multi-configuration generators.
+	Arguments:
+		- name: The name of the new configuration
+		- clone_config: The name of the configuration to clone compile flags from
+		- enable: Enable or disable configuration
+]]
+function(enable_configuration_type name clone_config enable)
+	if(CMAKE_CONFIGURATION_TYPES)
+		string(TOUPPER "${name}" name_upper)
+		string(TOUPPER "${clone_config}" clone_config_upper)
+		if(enable)
+			list(APPEND CMAKE_CONFIGURATION_TYPES "${name}")
+			list(REMOVE_DUPLICATES CMAKE_CONFIGURATION_TYPES)
+			set("CMAKE_MAP_IMPORTED_CONFIG_${name_upper}" "${name};${clone_config}" CACHE INTERNAL "" FORCE)
+			set("CMAKE_C_FLAGS_${name_upper}" "${CMAKE_C_FLAGS_${clone_config_upper}}" CACHE INTERNAL "" FORCE)
+			set("CMAKE_CXX_FLAGS_${name_upper}" "${CMAKE_CXX_FLAGS_${clone_config_upper}}" CACHE INTERNAL "" FORCE)
+			set("CMAKE_EXE_LINKER_FLAGS_${name_upper}" "${CMAKE_EXE_LINKER_FLAGS_${clone_config_upper}}" CACHE INTERNAL "" FORCE)
+			set("CMAKE_SHARED_LINKER_FLAGS_${name_upper}" "${CMAKE_SHARED_LINKER_FLAGS_${clone_config_upper}}" CACHE INTERNAL "" FORCE)
+		else()
+			list(REMOVE_ITEM CMAKE_CONFIGURATION_TYPES "${name}")
+		endif()
+		set(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING "List of configurations to enable" FORCE)
+	endif()
+endfunction()

+ 0 - 181
CMake/builddist.py

@@ -1,181 +0,0 @@
-#!/usr/bin/python
-import subprocess
-import os
-import sys
-import getopt
-import traceback
-import shutil
-import re
-
-def Usage(args):
-	print(sys.argv[0] + ' [-h] [-s] [-b] [-a] [-v version]')
-	print('')
-	print(' -h\t: This help screen')
-	print(' -s\t: Include full source code and build files')
-	print(' -b\t: Include sample binaries')
-	print(' -a\t: Create archive using 7z')
-	print(' -v\t: Specify RmlUi version')
-	print('')
-	sys.exit()
-
-def CheckVSVars():
-	if 'VCINSTALLDIR' in os.environ:
-		return
-		
-	if not 'VS90COMNTOOLS' in os.environ:
-		print("Unable to find VS9 install - check your VS90COMNTOOLS environment variable")
-		sys.exit()
-		
-	path = os.environ['VS90COMNTOOLS']
-	subprocess.call('"' + path + 'vsvars32.bat" > NUL && ' + ' '.join(sys.argv))
-	sys.exit()
-	
-def ProcessOptions(args):
-
-	options = {'RMLUI_VERSION': 'custom', 'FULL_SOURCE': False, 'ARCHIVE_NAME': 'RmlUi-sdk', 'SAMPLE_BINARIES': False, 'ARCHIVE': False}
-	
-	try:
-		optlist, args = getopt.getopt(args, 'v:hsba')
-	except getopt.GetoptError as e:
-		print('\nError: ' + str(e) + '\n')
-		Usage(args)
-	
-	for opt in optlist:
-		if opt[0] == '-h':
-			Usage(args)
-		if opt[0] == '-v':
-			options['RMLUI_VERSION'] = opt[1]
-		if opt[0] == '-s':
-			options['FULL_SOURCE'] = True
-			options['ARCHIVE_NAME'] = 'RmlUi-source'
-		if opt[0] == '-b':
-			options['SAMPLE_BINARIES'] = True
-		if opt[0] == '-a':
-			options['ARCHIVE'] = True
-			
-	return options
-		
-def Build(project, configs, defines = {}):
-
-	old_cl = ''
-	if 'CL' in os.environ:
-		old_cl = os.environ['CL']
-	else:
-		os.environ['CL'] = ''
-
-	for name, value in defines.items():
-		os.environ['CL'] = os.environ['CL'] + ' /D' + name + '=' + value
-		
-	for config in configs:
-		cmd = '"' + os.environ['VCINSTALLDIR'] + '\\vcpackages\\vcbuild.exe" /rebuild ' + project + '.vcproj "' + config + '|Win32"'
-		ret = subprocess.call(cmd)
-		if ret != 0:
-			print("Failed to build " + project)
-			sys.exit()
-			
-	os.environ['CL'] = old_cl
-	
-def DelTree(path):
-	if not os.path.exists(path):
-		return
-		
-	print('Deleting ' + path + '...')
-	for root, dirs, files in os.walk(path, topdown=False):
-		for name in files:
-			os.remove(os.path.join(root, name))
-		for name in dirs:
-			os.rmdir(os.path.join(root, name))
-
-def CopyFiles(source_path, destination_path, file_list = [], exclude_directories = [], exclude_files = [], preserve_paths = True):
-	working_directory = os.getcwd()
-	source_directory = os.path.abspath(os.path.join(working_directory, os.path.normpath(source_path)))
-	destination_directory = os.path.abspath(os.path.join(working_directory, os.path.normpath(destination_path)))
-	print("Copying " + source_directory + " to " + destination_directory + " ...")
-	
-	if not os.path.exists(source_directory):
-		print("Warning: Source directory " + source_directory + " doesn't exist.")
-		return False
-	
-	for root, directories, files in os.walk(source_directory, topdown=True):
-		directories[:] = [d for d in directories if d not in exclude_directories]
-		
-		for file in files:
-			# Skip files not in the include list.
-			if len(file_list) > 0:
-				included = False
-				for include in file_list:
-					if re.search(include, file):
-						included = True
-						break;
-
-				if not included:
-					continue
-			
-			# Determine our subdirectory.
-			subdir = root.replace(source_directory, "")
-			if subdir[:1] == os.path.normcase('/'):
-				subdir = subdir[1:]
-			
-			# Skip paths in the exclude list
-			excluded = False
-			for exclude in exclude_files:
-				if re.search(exclude, file):
-					excluded = True
-					break
-					
-			if excluded:
-				continue
-			
-			# Build up paths
-			source_file = os.path.join(root, file)
-			destination_subdir = destination_directory
-			if preserve_paths:
-				destination_subdir = os.path.join(destination_directory, subdir)
-			
-			if not os.path.exists(destination_subdir):
-				os.makedirs(destination_subdir)
-			destination_file = os.path.join(destination_subdir, file)
-			
-			# Copy files
-			try:
-				shutil.copy(source_file, destination_file)
-			except:
-				print("Failed copying " + source_file + " to " + destination_file)
-				traceback.print_exc()
-					
-	return True
-	
-def Archive(archive_name, path):
-	cwd = os.getcwd()
-	os.chdir(path + '/..')
-	file_name = archive_name + '.zip'
-	if os.path.exists(file_name):
-		os.unlink(file_name)
-	os.system('7z a ' + file_name + ' ' + path[path.rfind('/')+1:])
-	os.chdir(cwd)
-	
-def main():
-	options = ProcessOptions(sys.argv[1:])
-	
-	#CheckVSVars()
-	#Build('RmlCore', ['Debug', 'Release'], {'RMLUI_VERSION': '\\"' + options['RMLUI_VERSION'] + '\\"'})
-	#Build('RmlControls', ['Debug', 'Release'])
-	#Build('RmlDebugger', ['Debug', 'Release'])
-	
-	DelTree('../Distribution/RmlUi')
-	CopyFiles('../Include', '../Distribution/RmlUi/Include')
-	CopyFiles('../Build', '../Distribution/RmlUi/Build', ['\.dll$', '^Rml.*\.lib$'], ['CMakeFiles'])
-	CopyFiles('../CMake', '../Distribution/RmlUi/CMake', ['\.cmake$', '\.in$', '\.plist$', '\.py$', '\.sh$'])
-	CopyFiles('../Samples', '../Distribution/RmlUi/Samples', ['\.h$', '\.cpp$', '\.rml$', '\.rcss$', '\.tga$', '\.py$', '\.otf$', '\.ttf$', '\.txt$'])
-	if options['FULL_SOURCE']:
-		CopyFiles('../Build', '../Distribution/RmlUi/Build', ['\.vcxproj$', '\.sln$', '\.vsprops$', '\.py$'], ['CMakeFiles'])
-		CopyFiles('../Source', '../Distribution/RmlUi/Source', ['\.cpp$', '\.h$', '\.inl$'])
-	if options['SAMPLE_BINARIES']:
-		CopyFiles('../Build', '../Distribution/RmlUi/Build', ['\.exe$'], ['CMakeFiles'])
-	shutil.copyfile('../LICENSE', '../Distribution/RmlUi/LICENSE')
-	shutil.copyfile('../readme.md', '../Distribution/RmlUi/readme.md')
-	if options['ARCHIVE']:
-		Archive(options['ARCHIVE_NAME'] + '-' + options['RMLUI_VERSION'], '../Distribution/RmlUi');
-	
-if __name__ == '__main__':
-	main()

+ 0 - 80
CMake/gen_filelists.sh

@@ -1,80 +0,0 @@
-#!/usr/bin/env bash
-
-basedir=".."
-file=CMake/FileList.cmake
-src='set(lib_SRC_FILES'
-hdr='set(lib_HDR_FILES'
-masterpubhdr='set(MASTER_lib_PUB_HDR_FILES'
-pubhdr='set(lib_PUB_HDR_FILES'
-srcdir='${PROJECT_SOURCE_DIR}'
-fontdefaultbegin='if(NOT NO_FONT_INTERFACE_DEFAULT)'
-fontdefaultend='endif()'
-srcpath=Source
-hdrpath=Include/RmlUi
-fontdefaultpath=FontEngineDefault
-
-printfiles() {
-    # Print headers
-    echo ${hdr/lib/$1} >>$file
-    find  $srcpath/$1 -maxdepth 3 -path */$fontdefaultpath -prune -o \( -iname "*.h" -o -iname "*.hpp" \) -exec echo '    '$srcdir/{} \; 2>/dev/null | sort -f >>$file
-    echo -e ')\n' >>$file
-    # Print master header for library
-    echo ${masterpubhdr/lib/$1} >>$file
-    echo '    '$srcdir/Include/RmlUi/$1.h >>$file
-    echo -e ')\n' >>$file
-    # Print public headers sub directory
-    echo ${pubhdr/lib/$1} >>$file
-	if [[ "$1" == "Core" ]]; then echo '    '$srcdir/Include/RmlUi/Config/Config.h >>$file; fi
-    find  $hdrpath/$1 -maxdepth 3 -path */$fontdefaultpath -prune -o \( -iname "*.h" -o -iname "*.inl" -o -iname "*.hpp" \) -exec echo '    '$srcdir/{} \; 2>/dev/null | sort -f >>$file
-    echo -e ')\n' >>$file
-    # Print source files
-    echo ${src/lib/$1} >>$file
-    find  $srcpath/$1 -maxdepth 3 -path */$fontdefaultpath -prune -o -iname "*.cpp" -exec echo '    '$srcdir/{} \; 2>/dev/null | sort -f >>$file
-    echo -e ')\n' >>$file
-}
-
-printfontdefaultfiles() {
-    # Print headers
-	echo $fontdefaultbegin >>$file
-    echo '    '${hdr/lib/$1} >>$file
-    echo '        ${'$1'_HDR_FILES}' >>$file
-    find  $srcpath/$1/$fontdefaultpath -iname "*.h" -exec echo '        '$srcdir/{} \; 2>/dev/null | sort -f >>$file
-    echo -e '    )\n' >>$file
-    # Print source files
-    echo '    '${src/lib/$1} >>$file
-    echo '        ${'$1'_SRC_FILES}' >>$file
-    find  $srcpath/$1/$fontdefaultpath -iname "*.cpp" -exec echo '        '$srcdir/{} \; 2>/dev/null | sort -f >>$file
-    echo -e '    )' >>$file
-	echo -e $fontdefaultend'\n' >>$file
-}
-
-printpluginfiles() {
-    # Print headers
-    echo ${hdr/lib/$1} >>$file
-    find  $srcpath/$1 -iname "*.h" -exec echo '    '$srcdir/{} \; 2>/dev/null | sort -f >>$file
-    echo -e ')\n' >>$file
-    # Print public headers
-    echo ${pubhdr/lib/$1} >>$file
-    find  $hdrpath/$1 -iname "*.h" -exec echo '    '$srcdir/{} \; 2>/dev/null | sort -f >>$file 2>/dev/null
-    echo -e ')\n' >>$file
-    # Print source files
-    echo ${src/lib/$1} >>$file
-    find  $srcpath/$1 -iname "*.cpp" -exec echo '    '$srcdir/{} \; 2>/dev/null | sort -f >>$file
-    echo -e ')\n' >>$file
-}
-
-pushd $basedir
-echo -e "# This file was auto-generated with gen_filelists.sh\n" >$file
-for lib in "Core" "Debugger"; do
-    printfiles $lib
-done
-
-printfontdefaultfiles "Core"
-
-printpluginfiles "Lua"
-
-printpluginfiles "Lottie"
-
-printpluginfiles "SVG"
-
-popd

+ 0 - 34
CMake/gen_samplelists.sh

@@ -1,34 +0,0 @@
-#!/usr/bin/env bash
-
-basedir=".."
-file=CMake/SampleFileList.cmake
-src='set(sample_SRC_FILES'
-hdr='set(sample_HDR_FILES'
-srcdir='${PROJECT_SOURCE_DIR}'
-srcpath=Samples
-samples=( 'shell'
-	'basic/animation' 'basic/benchmark' 'basic/bitmapfont' 'basic/customlog' 'basic/databinding' 'basic/demo' 'basic/drag' 'basic/effects' 'basic/loaddocument' 'basic/treeview' 'basic/transform'
-	'basic/harfbuzzshaping' 'basic/lottie' 'basic/svg'
-	'tutorial/template' 'tutorial/drag'
-	'invaders' 'luainvaders'
-)
-
-printfiles() {
-    # Print headers
-    name=${1//basic\//} #substitute basic/ for nothing
-    name=${name//tutorial\//tutorial_} #substitute 'tutorial/' for 'tutorial_'
-    echo ${hdr/sample/$name} >>$file
-    find  $srcpath/$1/src -maxdepth 1 -iname "*.h" -exec echo '    '$srcdir/{} \; 2>/dev/null | sort -f >>$file
-    find  $srcpath/$1/include -maxdepth 1 -iname "*.h" -exec echo '    '$srcdir/{} \; 2>/dev/null | sort -f >>$file 2>/dev/null
-    echo -e ')\n' >>$file
-    # Print source files
-    echo ${src/sample/$name} >>$file
-    find  $srcpath/$1/src -maxdepth 1 -iname "*.cpp" -exec echo '    '$srcdir/{} \; 2>/dev/null | sort -f >>$file
-    echo -e ')\n' >>$file
-}
-
-pushd $basedir
-echo -e "# This file was auto-generated with gen_samplelists.sh\n" >$file
-for sample in ${samples[@]}; do
-    printfiles $sample
-done

+ 0 - 22
CMake/plist/RocketControlsOSX-Info.plist

@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-	<key>CFBundleDevelopmentRegion</key>
-	<string>English</string>
-	<key>CFBundleExecutable</key>
-	<string>${EXECUTABLE_NAME}</string>
-	<key>CFBundleIdentifier</key>
-	<string>com.yourcompany.${PRODUCT_NAME:rfc1034identifier}</string>
-	<key>CFBundleInfoDictionaryVersion</key>
-	<string>6.0</string>
-	<key>CFBundlePackageType</key>
-	<string>FMWK</string>
-	<key>CFBundleShortVersionString</key>
-	<string>1.0</string>
-	<key>CFBundleSignature</key>
-	<string>????</string>
-	<key>CFBundleVersion</key>
-	<string>1</string>
-</dict>
-</plist>

+ 0 - 22
CMake/plist/RocketCoreOSX-Info.plist

@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-	<key>CFBundleDevelopmentRegion</key>
-	<string>English</string>
-	<key>CFBundleExecutable</key>
-	<string>${EXECUTABLE_NAME}</string>
-	<key>CFBundleIdentifier</key>
-	<string>com.yourcompany.${PRODUCT_NAME:rfc1034identifier}</string>
-	<key>CFBundleInfoDictionaryVersion</key>
-	<string>6.0</string>
-	<key>CFBundlePackageType</key>
-	<string>FMWK</string>
-	<key>CFBundleShortVersionString</key>
-	<string>1.0</string>
-	<key>CFBundleSignature</key>
-	<string>????</string>
-	<key>CFBundleVersion</key>
-	<string>1</string>
-</dict>
-</plist>

+ 0 - 22
CMake/plist/RocketDebuggerOSX-Info.plist

@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-	<key>CFBundleDevelopmentRegion</key>
-	<string>English</string>
-	<key>CFBundleExecutable</key>
-	<string>${EXECUTABLE_NAME}</string>
-	<key>CFBundleIdentifier</key>
-	<string>com.yourcompany.${PRODUCT_NAME:rfc1034identifier}</string>
-	<key>CFBundleInfoDictionaryVersion</key>
-	<string>6.0</string>
-	<key>CFBundlePackageType</key>
-	<string>FMWK</string>
-	<key>CFBundleShortVersionString</key>
-	<string>1.0</string>
-	<key>CFBundleSignature</key>
-	<string>????</string>
-	<key>CFBundleVersion</key>
-	<string>1</string>
-</dict>
-</plist>

+ 152 - 1092
CMakeLists.txt

@@ -1,1153 +1,213 @@
-#===================================
-# Build script for RmlUi ===========
-#===================================
-
-cmake_minimum_required(VERSION 3.5)
-
-if(APPLE)
-	# This has to be before most other options so CMake properly handles the
-	# compiler variables, it MUST bebefore the project() definition
-	if(IOS_PLATFORM)
-		set(CMAKE_TOOLCHAIN_FILE CMake/Platform/iOS.cmake)
-	endif(IOS_PLATFORM)
-
-	option(BUILD_UNIVERSAL_BINARIES "Build universal binaries for all architectures supported" ON)
-	if (NOT CMAKE_OSX_ARCHITECTURES AND BUILD_UNIVERSAL_BINARIES)
-		if(IOS)
-			# set the architecture for iOS
-			if (${IOS_PLATFORM} STREQUAL "OS")
-				set (IOS_ARCH armv6 armv7 armv7s arm64)
-				set (CMAKE_OSX_ARCHITECTURES ${IOS_ARCH} CACHE STRING  "Build architecture for iOS")
-			else (${IOS_PLATFORM} STREQUAL "OS")
-				set (IOS_ARCH x86_64)
-				set (CMAKE_OSX_ARCHITECTURES ${IOS_ARCH} CACHE STRING  "Build architecture for iOS Simulator")
-			endif (${IOS_PLATFORM} STREQUAL "OS")
-
-		else(IOS)
-			# set the architectures for OS X
-			set (OSXI_ARCH x86_64)
-			set (CMAKE_OSX_ARCHITECTURES ${OSXI_ARCH} CACHE STRING  "Build architecture for OS X universal binaries")
-		endif(IOS)
-	endif (NOT CMAKE_OSX_ARCHITECTURES AND BUILD_UNIVERSAL_BINARIES)
-endif(APPLE)
-
-if(COMMAND cmake_policy)
-	cmake_policy(SET CMP0015 NEW)
-endif(COMMAND cmake_policy)
-
-# Enable the use of MACOSX_RPATH by default for CMake v3.0+; this effectively
-# allows plug 'n' play functionality, so to speak -- the resulting shared
-# library files can simply be copied over into the end-user's application
-# bundle or framework bundle. No mucking around with install_name_tool.
-#
-# 	See also:
-# cmake --help-policy cmp0042
-# http://www.kitware.com/blog/home/post/510
-if(POLICY CMP0042)
-	cmake_policy(SET CMP0042 NEW)
-endif(POLICY CMP0042)
-if (POLICY CMP0072)
-	cmake_policy (SET CMP0072 NEW)
-endif(POLICY CMP0072)
-if(POLICY CMP0074)
-	cmake_policy(SET CMP0074 NEW)
-endif(POLICY CMP0074)
-if(POLICY CMP0092)
-	cmake_policy(SET CMP0092 NEW)
-endif(POLICY CMP0092)
-
-project(RmlUi LANGUAGES C CXX VERSION 6.0)
-
-set(RMLUI_VERSION_RELEASE false)
-
-if(RMLUI_VERSION_RELEASE)
-	set(RMLUI_VERSION_SUFFIX "")
-else()
-	set(RMLUI_VERSION_SUFFIX "-dev")
-endif()
-
-set(RMLUI_VERSION_SHORT ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}${RMLUI_VERSION_SUFFIX})
+# Using CMake 3.10 as minimum to support all platforms of interest
+# https://github.com/mikke89/RmlUi/issues/198#issuecomment-1246957062
+cmake_minimum_required(VERSION 3.10...3.27)
+
+project("RmlUi"
+	VERSION "6.0"
+	DESCRIPTION "C++ user interface library based on the HTML and CSS standards"
+	LANGUAGES "C" "CXX"
+)
 
 
-list(APPEND CORE_PRIVATE_DEFS RMLUI_VERSION="${RMLUI_VERSION_SHORT}")
+set(RMLUI_VERSION_RELEASE FALSE)
 
 
 if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
 if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
-	option(BUILD_TESTING "" OFF)
-	include(CTest)
-
-	if(BUILD_TESTING)
-		set(RMLUI_TESTS_ENABLED ON)
-		set(VISUAL_TESTS_RML_DIRECTORIES "" CACHE PATH "Specify additional directories containing *.rml test documents for VisualTests. Separate multiple directories by comma.")
-		set(VISUAL_TESTS_COMPARE_DIRECTORY "" CACHE PATH "Set the input directory for screenshot comparison performed by VisualTests.")
-		set(VISUAL_TESTS_CAPTURE_DIRECTORY "" CACHE PATH "Set the output directory for screenshots generated by VisualTests.")
-	endif()
+	set(RMLUI_IS_ROOT_PROJECT TRUE)
 endif()
 endif()
 
 
-# paths
-include(GNUInstallDirs)
-
-# Search in the 'cmake' directory for additional CMake modules.
-list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMake;${PROJECT_SOURCE_DIR}/CMake/Modules)
-
-#===================================
-# Environment tests ================
-#===================================
+# Add lists of available options for those that support it
+include("CMake/OptionsLists.cmake")
 
 
-include(TestForANSIForScope)
-include(TestForANSIStreamHeaders)
-include(TestForSTDNamespace)
+option(BUILD_SHARED_LIBS "CMake standard option. Choose whether to build shared RmlUi libraries." ON)
 
 
-#===================================
-# Provide hints as to where depends=
-# might be found                   =
-#===================================
-
-if(NOT DEFINED ENV{FREETYPE_DIR})
-	set(ENV{FREETYPE_DIR} "${PROJECT_SOURCE_DIR}/Dependencies")
-endif()
-
-if(NOT DEFINED ENV{LUA_DIR})
-	set(ENV{LUA_DIR} "${PROJECT_SOURCE_DIR}/Dependencies")
-endif()
-
-if(NOT DEFINED ENV{SDL2DIR})
-	set(ENV{SDL2DIR} "${PROJECT_SOURCE_DIR}/Dependencies")
-endif()
-
-if(NOT DEFINED ENV{SDL2_IMAGE_DIR})
-	set(ENV{SDL2_IMAGE_DIR} "${PROJECT_SOURCE_DIR}/Dependencies")
-endif()
-
-if(NOT DEFINED ENV{SFML_ROOT})
-	set(ENV{SFML_ROOT} "${PROJECT_SOURCE_DIR}/Dependencies")
+# Declare project-specific options. Naming conventions:
+#   - 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.
+option(RMLUI_SAMPLES "Build samples of the library." OFF)
+set(RMLUI_BACKEND "auto" CACHE STRING "Backend to use when building the RmlUi samples. Choose one from ./CMake/OptionsLists.cmake.")
+set_property(CACHE RMLUI_BACKEND PROPERTY STRINGS ${RMLUI_BACKEND_OPTIONS})
+if(NOT RMLUI_BACKEND IN_LIST RMLUI_BACKEND_OPTIONS)
+	message(FATAL_ERROR "The RmlUi backend '${RMLUI_BACKEND}' specified in RMLUI_BACKEND is not valid. Available options: ${RMLUI_BACKEND_OPTIONS}")
 endif()
 endif()
 
 
-if(NOT DEFINED ENV{TRACY_DIR})
-	set(ENV{TRACY_DIR} "${PROJECT_SOURCE_DIR}/Dependencies")
-endif()
-
-if(NOT DEFINED ENV{RLOTTIE_DIR})
-	set(ENV{RLOTTIE_DIR} "${PROJECT_SOURCE_DIR}/Dependencies/rlottie")
-endif()
-
-if(NOT DEFINED ENV{LUNASVG_DIR})
-	set(ENV{LUNASVG_DIR} "${PROJECT_SOURCE_DIR}/Dependencies/lunasvg")
-endif()
-
-#===================================
-# Plaform specific global hacks ====
-#===================================
-
-if(APPLE)
-	# Disables naked builtins from AssertMacros.h which
-	# This prevents naming collisions such as those from the check()
-	# function macro with LuaType::check
-	add_definitions(-D__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES=0)
-endif(APPLE)
-
-#===================================
-# Build options ====================
-#===================================
-
-if(NOT CMAKE_BUILD_TYPE)
-	set(CMAKE_BUILD_TYPE Release CACHE STRING
-		"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
-		FORCE)
+set(RMLUI_FONT_ENGINE "freetype" CACHE STRING "Font engine to build RmlUi with. If set to \"none\", RmlUi won't build with any of the included font engines and some samples might be disabled.")
+set_property(CACHE RMLUI_FONT_ENGINE PROPERTY STRINGS ${RMLUI_FONT_ENGINE_OPTIONS})
+if(NOT RMLUI_FONT_ENGINE IN_LIST RMLUI_FONT_ENGINE_OPTIONS)
+	message(FATAL_ERROR "The RmlUi font engine '${RMLUI_FONT_ENGINE}' specified in RMLUI_FONT_ENGINE is not valid. Available options: ${RMLUI_FONT_ENGINE_OPTIONS}")
 endif()
 endif()
-
-if(NOT IOS)
-	option(BUILD_SHARED_LIBS "Build shared (dynamic) libraries" ON)
-endif(NOT IOS)
-
-option(BUILD_LUA_BINDINGS "Build Lua bindings" OFF)
-
-if (BUILD_LUA_BINDINGS)
-	option(BUILD_LUA_BINDINGS_FOR_LUAJIT "Build Lua bindings using luajit" OFF)
-	option(RMLUI_LUA_AS_CXX "Lua library was compiled with a C++ compiler" OFF)
-endif()
-
-if(APPLE)
-	option(BUILD_FRAMEWORK "Build Framework bundle for OSX" OFF)
-endif()
-
-option(BUILD_SAMPLES "Build samples" OFF)
-option(ENABLE_HARFBUZZ "Enable HarfBuzz for text-shaping sample. Requires the HarfBuzz library." OFF)
-
-set(SAMPLES_BACKEND "auto" CACHE STRING "Backend platform and renderer used for the samples.")
-set_property(CACHE SAMPLES_BACKEND PROPERTY STRINGS auto Win32_GL2 Win32_VK X11_GL2 SDL_GL2 SDL_GL3 SDL_VK SDL_SDLrenderer SFML_GL2 GLFW_GL2 GLFW_GL3 GLFW_VK BackwardCompatible_GLFW_GL2 BackwardCompatible_GLFW_GL3)
-
-if(SAMPLES_BACKEND STREQUAL "auto")
-	if(EMSCRIPTEN)
-		set(SAMPLES_BACKEND SDL_GL3)
-	elseif(WIN32)
-		set(SAMPLES_BACKEND Win32_GL2)
-	elseif(APPLE)
-		set(SAMPLES_BACKEND SDL_SDLrenderer)
-	else()
-		set(SAMPLES_BACKEND X11_GL2)
-	endif()
+if(RMLUI_FONT_ENGINE STREQUAL "none")
+	set(RMLUI_FONT_ENGINE_ENABLED FALSE)
+else()
+	set(RMLUI_FONT_ENGINE_ENABLED TRUE)
 endif()
 endif()
 
 
-option(MATRIX_ROW_MAJOR "Use row-major matrices. Column-major matrices are used by default." OFF)
-
-if(APPLE)
-	if(IOS)
-		if(BUILD_SHARED_LIBS)
-			message(FATAL_ERROR "BUILD_SHARED_LIBS must be OFF for iOS builds.  iOS does not support shared libraries.")
-		endif(BUILD_SHARED_LIBS)
-	endif(IOS)
-
-	if(BUILD_FRAMEWORK)
-		if(NOT "${CMAKE_GENERATOR}" STREQUAL "Xcode")
-			message(FATAL_ERROR "You should use Xcode generator with BUILD_FRAMEWORK enabled")
-		endif()
-		if(NOT BUILD_SHARED_LIBS)
-			message(FATAL_ERROR "BUILD_SHARED_LIBS must be ON with BUILD_FRAMEWORK enabled")
+if(RMLUI_IS_ROOT_PROJECT)
+	option(BUILD_TESTING "CMake standard option. Enable RmlUi testing projects." OFF)
+	if(BUILD_TESTING)
+		enable_testing()
+		set(RMLUI_TESTS ON)
+		set(RMLUI_VISUAL_TESTS_RML_DIRECTORIES "" CACHE PATH "Specify additional directories containing *.rml test documents for VisualTests. Separate multiple directories by comma.")
+		set(RMLUI_VISUAL_TESTS_COMPARE_DIRECTORY "" CACHE PATH "Set the input directory for screenshot comparison performed by VisualTests.")
+		set(RMLUI_VISUAL_TESTS_CAPTURE_DIRECTORY "" CACHE PATH "Set the output directory for screenshots generated by VisualTests.")
+		if(WIN32 AND BUILD_SHARED_LIBS AND NOT CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS)
+			message(FATAL_ERROR "The RmlUi testing framework cannot be built when using shared libraries with default visibility on Windows. "
+				"Please disable either BUILD_SHARED_LIBS or BUILD_TESTING.")
 		endif()
 		endif()
 	endif()
 	endif()
-else(APPLE)
-	if(BUILD_FRAMEWORK)
-		message(FATAL_ERROR "BUILD_FRAMEWORK is only supported on Mac OS X with the Xcode generator")
-	endif()
-endif(APPLE)
-
-option(NO_FONT_INTERFACE_DEFAULT "Do not include the default font engine in the build. Allows building without the FreeType dependency, but a custom font engine must be created and set." OFF)
-if(NO_FONT_INTERFACE_DEFAULT)
-	list(APPEND CORE_PRIVATE_DEFS RMLUI_NO_FONT_INTERFACE_DEFAULT)
-endif()
-
-if(WIN32 AND BUILD_SHARED_LIBS AND BUILD_TESTING)
-	message(FATAL_ERROR "-- The RmlUi testing framework cannot be built when using shared libraries on Windows. Please disable either BUILD_SHARED_LIBS or BUILD_TESTING.")
-endif()
-
-if(EMSCRIPTEN AND BUILD_SHARED_LIBS)
-	message(FATAL_ERROR "-- Dynamic libraries not supported when using Emscripten. Please disable BUILD_SHARED_LIBS.")
-endif()
-
-if(NOT BUILD_SHARED_LIBS)
-	list(APPEND CORE_PUBLIC_DEFS -DRMLUI_STATIC_LIB)
-	message("-- Building static libraries. Make sure to #define RMLUI_STATIC_LIB before including RmlUi in your project.")
 endif()
 endif()
 
 
-option(NO_THIRDPARTY_CONTAINERS "Only use standard library containers." OFF)
-if( NO_THIRDPARTY_CONTAINERS )
-	list(APPEND CORE_PUBLIC_DEFS -DRMLUI_NO_THIRDPARTY_CONTAINERS)
-	message("-- No third-party containers will be used: Make sure to #define RMLUI_NO_THIRDPARTY_CONTAINERS before including RmlUi in your project.")
-endif()
-
-option(CUSTOM_CONFIGURATION "Customize RmlUi configuration files for overriding the default configuration and types." OFF)
-
-set(CUSTOM_CONFIGURATION_FILE "" CACHE STRING "Custom configuration file to be included in place of <RmlUi/Config/Config.h>.")
-if( CUSTOM_CONFIGURATION AND CUSTOM_CONFIGURATION_FILE )
-	list(APPEND CORE_PUBLIC_DEFS -DRMLUI_CUSTOM_CONFIGURATION_FILE="${CUSTOM_CONFIGURATION_FILE}")
-	message("-- Including ${CUSTOM_CONFIGURATION_FILE} instead of <RmlUi/Config/Config.h>")
-endif ()
-
-set(CUSTOM_INCLUDE_DIRS "" CACHE STRING "Extra include directories (use with CUSTOM_CONFIGURATION_FILE).")
-if( CUSTOM_CONFIGURATION AND CUSTOM_INCLUDE_DIRS )
-	include_directories(${CUSTOM_INCLUDE_DIRS})
-endif ()
-
-set(CUSTOM_LINK_LIBRARIES "" CACHE STRING "Extra link libraries (use with CUSTOM_CONFIGURATION_FILE).")
-
-if( CUSTOM_CONFIGURATION )
-	mark_as_advanced( CLEAR CUSTOM_CONFIGURATION_FILE CUSTOM_INCLUDE_DIRS CUSTOM_LINK_LIBRARIES )
-else()
-	mark_as_advanced( FORCE CUSTOM_CONFIGURATION_FILE CUSTOM_INCLUDE_DIRS CUSTOM_LINK_LIBRARIES )
-
-	if( CUSTOM_CONFIGURATION_FILE OR CUSTOM_INCLUDE_DIRS OR CUSTOM_LINK_LIBRARIES )
-		message("-- CUSTOM_CONFIGURATION disabled, but custom configuration variables are set. They will have no effect.")
+option(RMLUI_LUA_BINDINGS "Build Lua bindings." OFF)
+if(RMLUI_LUA_BINDINGS)
+	set(RMLUI_LUA_BINDINGS_LIBRARY "lua" CACHE STRING "Choose which library to use for lua bindings when enabled.")
+	set_property(CACHE RMLUI_LUA_BINDINGS_LIBRARY PROPERTY STRINGS ${RMLUI_LUA_BINDINGS_LIBRARY_OPTIONS})
+	if(NOT RMLUI_LUA_BINDINGS_LIBRARY IN_LIST RMLUI_LUA_BINDINGS_LIBRARY_OPTIONS)
+		message(FATAL_ERROR "The RmlUi Lua binding library '${RMLUI_LUA_BINDINGS_LIBRARY}' specified in RMLUI_LUA_BINDINGS_LIBRARY is not valid. Available options: ${RMLUI_LUA_BINDINGS_LIBRARY_OPTIONS}")
 	endif()
 	endif()
 endif()
 endif()
 
 
-function(EnableConfigurationType name enable)
-	if(enable)
-		list(APPEND CMAKE_CONFIGURATION_TYPES "${name}")
-		list(REMOVE_DUPLICATES CMAKE_CONFIGURATION_TYPES)
-	else()
-		list(REMOVE_ITEM CMAKE_CONFIGURATION_TYPES "${name}")
-	endif()
-	set(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING "List of configurations to enable" FORCE)
-endfunction()
+option(RMLUI_LOTTIE_PLUGIN "Enable plugin for Lottie animations. Requires the rlottie library." OFF)
+option(RMLUI_SVG_PLUGIN "Enable plugin for SVG images. Requires the lunasvg library." OFF)
 
 
-option(RMLUI_TRACY_PROFILING "Enable profiling with Tracy. Source files can be placed in Dependencies/tracy." OFF)
-if( RMLUI_TRACY_PROFILING )
-	option(RMLUI_TRACY_MEMORY_PROFILING "Overload global operator new/delete to track memory allocations in Tracy." ON)
+option(RMLUI_HARFBUZZ_SAMPLE "Enable harfbuzz text shaping sample. Requires the harfbuzz library." OFF)
 
 
-	if( CMAKE_CONFIGURATION_TYPES )
-		option(RMLUI_TRACY_CONFIGURATION "Enable a separate Tracy configuration type for multi-config generators such as Visual Studio, otherwise enable Tracy in all configurations." ON)
+option(RMLUI_THIRDPARTY_CONTAINERS "Enable integrated third-party containers for improved performance, rather than their standard library counterparts." ON)
 
 
-		if( RMLUI_TRACY_CONFIGURATION )
-			EnableConfigurationType(Tracy ON)
-			list(APPEND CMAKE_MAP_IMPORTED_CONFIG_TRACY Release)
-			set(CMAKE_C_FLAGS_TRACY "${CMAKE_C_FLAGS_RELEASE}")
-			set(CMAKE_CXX_FLAGS_TRACY "${CMAKE_CXX_FLAGS_RELEASE}")
-			set(CMAKE_EXE_LINKER_FLAGS_TRACY "${CMAKE_EXE_LINKER_FLAGS_RELEASE}")
-			set(CMAKE_SHARED_LINKER_FLAGS_TRACY "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}")
-		else()
-			EnableConfigurationType(Tracy OFF)
-		endif()
-	endif()
+option(RMLUI_MATRIX_ROW_MAJOR "Use row-major matrices. Column-major matrices are used by default." OFF)
 
 
-	if(NOT TARGET Tracy::TracyClient)
-		find_package(Tracy QUIET)
-	endif()
+option(RMLUI_CUSTOM_RTTI "Build RmlUi with a custom implementation of run-time type information (RTTI). When enabled, all usage of language RTTI features such as dynamic_cast will be disabled." OFF)
 
 
-	if(NOT TARGET Tracy::TracyClient)
-		message("Trying to add Tracy from subdirectory 'Dependencies/tracy'.")
-		add_subdirectory("Dependencies/tracy")
-	endif()
+option(RMLUI_PRECOMPILED_HEADERS "Enable precompiled headers for RmlUi." ON)
 
 
-	if(NOT TARGET Tracy::TracyClient)
-		message(FATAL_ERROR "Tracy client not found. Either (a) make sure target Tracy::TracyClient is available from parent project,"
-			"(b) Tracy can be found as a config package, or (c) Tracy source files are located in 'Dependencies/Tracy'.")
-	endif()
+option(RMLUI_COMPILER_OPTIONS "Enable recommended compiler-specific options for the project, such as for supported warning level, standards conformance, and multiprocess builds. Turn off for full control over compiler flags." ON)
 
 
-	if( CMAKE_CONFIGURATION_TYPES AND RMLUI_TRACY_CONFIGURATION )
-		message("-- Tracy profiling enabled in configuration 'Tracy'.")
-		set(RMLUI_TRACY_CONDITION "$<CONFIG:Tracy>")
-	else()
-		message("-- Tracy profiling enabled.")
-		set(RMLUI_TRACY_CONDITION "1")
-	endif()
+option(RMLUI_WARNINGS_AS_ERRORS "Treat compiler warnings as errors." OFF)
+mark_as_advanced(RMLUI_WARNINGS_AS_ERRORS)
 
 
-	list(APPEND CORE_PUBLIC_LINK_LIBS "$<${RMLUI_TRACY_CONDITION}:Tracy::TracyClient>")
-	list(APPEND CORE_PUBLIC_DEFS "$<${RMLUI_TRACY_CONDITION}:RMLUI_TRACY_PROFILING>")
-	if(RMLUI_TRACY_MEMORY_PROFILING)
-		list(APPEND CORE_PRIVATE_DEFS "$<${RMLUI_TRACY_CONDITION}:RMLUI_TRACY_MEMORY_PROFILING>")
-	endif()
-elseif( CMAKE_CONFIGURATION_TYPES )
-	EnableConfigurationType(Tracy OFF)
-endif()
-
-option(ENABLE_LOTTIE_PLUGIN "Enable plugin for Lottie animations. Requires the rlottie library." OFF)
-option(ENABLE_SVG_PLUGIN "Enable plugin for SVG images. Requires the lunasvg library." OFF)
-
-option(DISABLE_RTTI_AND_EXCEPTIONS "Build with rtti and exceptions disabled." OFF)
-if(DISABLE_RTTI_AND_EXCEPTIONS)
-	list(APPEND CORE_PUBLIC_DEFS -DRMLUI_USE_CUSTOM_RTTI)
-	message("-- C++ RTTI and exceptions will be disabled: Make sure to #define RMLUI_USE_CUSTOM_RTTI before including RmlUi in your project.")
+option(RMLUI_TRACY_PROFILING "Enable profiling with Tracy. Source files can optionally be placed in `Dependencies/tracy`." OFF)
+if(RMLUI_TRACY_PROFILING)
+	option(RMLUI_TRACY_MEMORY_PROFILING "Overload global operator new/delete to track memory allocations in Tracy." ON)
 endif()
 endif()
-
-option(ENABLE_PRECOMPILED_HEADERS "Enable precompiled headers" ON)
-set(PRECOMPILED_HEADERS_ENABLED OFF)
-if (ENABLE_PRECOMPILED_HEADERS AND (CMAKE_VERSION VERSION_LESS 3.16.0))
-	message("-- Could not enable precompiled headers. Need CMake version 3.16.0 or greater.")
-elseif (ENABLE_PRECOMPILED_HEADERS)
-	set(PRECOMPILED_HEADERS_ENABLED ON)
+if(RMLUI_TRACY_PROFILING AND CMAKE_CONFIGURATION_TYPES)
+	option(RMLUI_TRACY_CONFIGURATION "Enable a separate Tracy configuration type for multi-config generators such as Visual Studio, otherwise enable Tracy in all configurations." ON)
 endif()
 endif()
 
 
-option(WARNINGS_AS_ERRORS "Treat compiler warnings as errors." OFF)
-mark_as_advanced(WARNINGS_AS_ERRORS)
-
-macro(add_common_target_options NAME)
-	# C++ language version
-	if(CMAKE_VERSION VERSION_LESS 3.8.0)
-		set_target_properties(${NAME} PROPERTIES
-			CXX_STANDARD 14
-			CXX_STANDARD_REQUIRED YES
-		)
-	else()
-		target_compile_features(${NAME} PUBLIC cxx_std_14)
-	endif()
-	set_target_properties(${NAME} PROPERTIES CXX_EXTENSIONS OFF)
-
-	# Compiler warnings
-	if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
-		target_compile_options(${NAME} PRIVATE -Wall -pedantic -Wextra)
-
-		if(WARNINGS_AS_ERRORS)
-			target_compile_options(${NAME} PRIVATE -Werror)
-		endif()
-	elseif(MSVC)
-		target_compile_options(${NAME} PRIVATE /MP /W4 /w44062 /permissive-)
-		target_compile_definitions(${NAME} PRIVATE _CRT_SECURE_NO_WARNINGS)
-
-		if(WARNINGS_AS_ERRORS)
-			target_compile_options(${NAME} PRIVATE /WX)
-		endif()
-	endif()
-endmacro()
-
-#===================================
-# Setup paths ======================
-#===================================
-
-include_directories(
-	${PROJECT_SOURCE_DIR}/Include
-)
-
-# Include list of source files
-include(FileList)
-
-#===================================
-# Find dependencies ================
-#===================================
-
-# FreeType
-if(NOT NO_FONT_INTERFACE_DEFAULT)
-	if(EMSCRIPTEN)
-		set(EMSCRIPTEN_FLAGS "${EMSCRIPTEN_FLAGS} -sUSE_FREETYPE=1")
-	else()
-		find_package(Freetype REQUIRED)
-		if(MSVC AND FREETYPE_VERSION_STRING STREQUAL "2.11.0")
-			message(WARNING "You are using FreeType version 2.11.0 which introduced an issue that causes a crash on startup on some of the samples. Please avoid this version specifically.")
-		endif()
-
-		list(APPEND CORE_LINK_LIBS ${FREETYPE_LIBRARIES})
-		list(APPEND CORE_INCLUDE_DIRS ${FREETYPE_INCLUDE_DIRS})
+option(RMLUI_CUSTOM_CONFIGURATION "Customize the RmlUi configuration file to override the default configuration and types." OFF)
+set(RMLUI_CUSTOM_CONFIGURATION_FILE "" CACHE STRING "Custom configuration file to be included in place of <RmlUi/Config/Config.h>.")
+set(RMLUI_CUSTOM_INCLUDE_DIRS "" CACHE STRING "Extra include directories (use with RMLUI_CUSTOM_CONFIGURATION_FILE).")
+set(RMLUI_CUSTOM_LINK_LIBRARIES "" CACHE STRING "Extra link libraries (use with RMLUI_CUSTOM_CONFIGURATION_FILE).")
+if(RMLUI_CUSTOM_CONFIGURATION)
+	mark_as_advanced(CLEAR RMLUI_CUSTOM_CONFIGURATION_FILE RMLUI_CUSTOM_INCLUDE_DIRS RMLUI_CUSTOM_LINK_LIBRARIES)
+else()
+	mark_as_advanced(FORCE RMLUI_CUSTOM_CONFIGURATION_FILE RMLUI_CUSTOM_INCLUDE_DIRS RMLUI_CUSTOM_LINK_LIBRARIES)
+	if(RMLUI_CUSTOM_CONFIGURATION_FILE OR RMLUI_CUSTOM_INCLUDE_DIRS OR RMLUI_CUSTOM_LINK_LIBRARIES)
+		message(STATUS "RMLUI_CUSTOM_CONFIGURATION is disabled, but custom configuration variables are set. They will have no effect.")
 	endif()
 	endif()
 endif()
 endif()
 
 
-# HarfBuzz
-if (ENABLE_HARFBUZZ)
-	if(NO_FONT_INTERFACE_DEFAULT)
-		message(FATAL_ERROR "The HarfBuzz sample requires the default (FreeType) font engine to be enabled. Please disable either NO_FONT_INTERFACE_DEFAULT or ENABLE_HARFBUZZ.")
-	endif()
-	if(WIN32 AND BUILD_SHARED_LIBS)
-		message(FATAL_ERROR "-- The HarfBuzz sample cannot be built when using shared libraries on Windows. Please disable either BUILD_SHARED_LIBS or ENABLE_HARFBUZZ.")
-	endif()
+set(RMLUI_INSTALL_TARGETS_DIR "" CACHE STRING "Override the install directory for the generated CMake targets.")
+mark_as_advanced(RMLUI_INSTALL_TARGETS_DIR)
+option(RMLUI_INSTALL_LICENSES_AND_BUILD_INFO "Install license files and build info intended for the github actions workflow." OFF)
+mark_as_advanced(RMLUI_INSTALL_LICENSES_AND_BUILD_INFO)
 
 
-	find_package(HarfBuzz REQUIRED)
-endif()
+# Add custom CMake modules path for external dependencies
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake/Modules")
+list(APPEND CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}/Dependencies")
 
 
-# Lua
-if(BUILD_LUA_BINDINGS)
-	if(BUILD_LUA_BINDINGS_FOR_LUAJIT)
-		find_package(LuaJIT REQUIRED)
-		list(APPEND LUA_BINDINGS_INCLUDE_DIRS ${LUAJIT_INCLUDE_DIR})
-		list(APPEND LUA_BINDINGS_LINK_LIBS ${LUAJIT_LIBRARY})
-	else()
-		find_package(Lua REQUIRED)
-		list(APPEND LUA_BINDINGS_INCLUDE_DIRS ${LUA_INCLUDE_DIR})
-		list(APPEND LUA_BINDINGS_LINK_LIBS ${LUA_LIBRARIES})
-	endif()
-	if(RMLUI_LUA_AS_CXX)
-		list(APPEND LUA_BINDINGS_PUBLIC_DEFS -DRMLUI_LUA_COMPILED_AS_CXX)
-	endif()
+include(GNUInstallDirs)
+if(NOT RMLUI_INSTALL_TARGETS_DIR)
+	set(RMLUI_INSTALL_TARGETS_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/RmlUi")
 endif()
 endif()
 
 
-# rlottie
-if( ENABLE_LOTTIE_PLUGIN AND TARGET rlottie::rlottie )
-	list(APPEND CORE_LINK_LIBS rlottie::rlottie)
-	list(APPEND CORE_INCLUDE_DIRS rlottie::rlottie)
-elseif( ENABLE_LOTTIE_PLUGIN )
-	# Try to find the rlottie library.
-	if(NOT DEFINED rlottie_DIR)
-		set(rlottie_DIR $ENV{RLOTTIE_DIR})
-	endif()
-
-	list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/Dependencies/rlottie/build)
-	find_package(rlottie CONFIG)
-	find_path(rlottie_INCLUDE_DIR rlottie.h HINTS ${rlottie_DIR} $ENV{rlottie_DIR} PATH_SUFFIXES inc rlottie/inc ../inc)
+include("CMake/Utilities.cmake")
+include("CMake/Dependencies.cmake")
 
 
-	if(rlottie_FOUND AND rlottie_INCLUDE_DIR)
-		message("-- Can Lottie plugin be added to RmlCore - yes - rlottie library found")
+include("CMake/RuntimeUtilities.cmake")
+setup_runtime_output_directory()
+setup_runtime_dependency_set_arg()
 
 
-		list(APPEND CORE_LINK_LIBS rlottie::rlottie)
-		list(APPEND CORE_INCLUDE_DIRS ${rlottie_INCLUDE_DIR})
-		list(APPEND CORE_PRIVATE_DEFS RMLUI_ENABLE_LOTTIE_PLUGIN)
+add_subdirectory("Source")
 
 
-		list(APPEND Core_HDR_FILES ${Lottie_HDR_FILES})
-		list(APPEND Core_PUB_HDR_FILES ${Lottie_PUB_HDR_FILES})
-		list(APPEND Core_SRC_FILES ${Lottie_SRC_FILES})
-	else()
-		if(rlottie_FOUND)
-			message(FATAL_ERROR "-- Can Lottie plugin be added to RmlCore - no - rlottie library found - rlottie include directory not found")
-		elseif(rlottie_INCLUDE_DIR)
-			message(FATAL_ERROR "-- Can Lottie plugin be added to RmlCore - no - rlottie library not found - rlottie include directory found at ${rlottie_INCLUDE_DIR}")
-		else()
-			message(FATAL_ERROR "-- Can Lottie plugin be added to RmlCore - no - rlottie not found")
-		endif()
-	endif()
+if(RMLUI_SAMPLES OR RMLUI_TESTS)
+	set(RMLUI_SHELL ON)
 endif()
 endif()
 
 
-# lunasvg
-if( ENABLE_SVG_PLUGIN )
-	if(NOT DEFINED LUNASVG_DIR)
-		set(LUNASVG_DIR $ENV{LUNASVG_DIR})
-	endif()
-
-	message("-- Can SVG plugin be enabled - looking for lunasvg library")
-
-	find_package(lunasvg REQUIRED)
-
-	list(APPEND CORE_LINK_LIBS ${LUNASVG_LIBRARIES})
-	list(APPEND CORE_INCLUDE_DIRS ${LUNASVG_INCLUDE_DIR})
-	list(APPEND CORE_PRIVATE_DEFS RMLUI_ENABLE_SVG_PLUGIN)
-
-	list(APPEND Core_HDR_FILES ${SVG_HDR_FILES})
-	list(APPEND Core_PUB_HDR_FILES ${SVG_PUB_HDR_FILES})
-	list(APPEND Core_SRC_FILES ${SVG_SRC_FILES})
-
-	message("-- Can SVG plugin be enabled - yes - lunasvg library found")
+if(RMLUI_SHELL)
+	include("CMake/BackendAutoSelection.cmake")
+	include("CMake/DependenciesForBackends.cmake")
+	add_subdirectory("Backends")
 endif()
 endif()
 
 
+add_subdirectory("Samples")
 
 
-if(NOT BUILD_FRAMEWORK)
-#===================================
-# Build libraries ==================
-#===================================
-
-set(LIBRARIES Core Debugger)
-
-foreach(library ${LIBRARIES})
-	set(NAME Rml${library})
-
-	add_library(${NAME}
-		${${library}_HDR_FILES}
-		${${library}_PUB_HDR_FILES}
-		${MASTER_${library}_PUB_HDR_FILES}
-		${${library}_SRC_FILES}
-	)
-	add_library(RmlUi::${library} ALIAS ${NAME})
-
-	set_target_properties(${NAME} PROPERTIES
-		VERSION ${PROJECT_VERSION}
-		SOVERSION ${PROJECT_VERSION_MAJOR}
-	)
-
-	add_common_target_options(${NAME})
-
-	install(TARGETS ${NAME}
-		EXPORT RmlUiTargets
-		LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-		ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-		RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-	)
-
-	set(RMLUI_EXPORTED_TARGETS ${RMLUI_EXPORTED_TARGETS} ${NAME})
-endforeach(library)
-
-if( CUSTOM_CONFIGURATION )
-	foreach(library ${CUSTOM_LINK_LIBRARIES})
-		install(TARGETS ${library}
-			EXPORT RmlUiTargets
-			LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-			ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-			RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-		)
-		set(RMLUI_EXPORTED_TARGETS ${RMLUI_EXPORTED_TARGETS} ${library})
-	endforeach(library ${CUSTOM_LINK_LIBRARIES})
+if(RMLUI_TESTS)
+	add_subdirectory("Tests")
 endif()
 endif()
 
 
-if( MATRIX_ROW_MAJOR )
-	list(APPEND CORE_PUBLIC_DEFS -DRMLUI_MATRIX_ROW_MAJOR)
-endif ()
-if( CUSTOM_CONFIGURATION AND CUSTOM_LINK_LIBRARIES )
-	target_link_libraries(RmlCore PUBLIC ${CUSTOM_LINK_LIBRARIES})
-endif ()
-
-if (PRECOMPILED_HEADERS_ENABLED)
-	target_precompile_headers(RmlCore PRIVATE ${PROJECT_SOURCE_DIR}/Source/Core/precompiled.h)
+# Add an interface library to include all sub-libraries.
+# RMLUI_CMAKE_MINIMUM_VERSION_RAISE_NOTICE:
+# From CMake 3.13 we can place target_link_libraries in the same source as each sub-library is declared, see CMP0079.
+add_library(rmlui INTERFACE)
+add_library(RmlUi::RmlUi ALIAS rmlui)
+target_link_libraries(rmlui INTERFACE rmlui_core rmlui_debugger)
+if(RMLUI_LUA_BINDINGS)
+	target_link_libraries(rmlui INTERFACE rmlui_lua)
 endif()
 endif()
+set_target_properties(rmlui PROPERTIES EXPORT_NAME "RmlUi")
+install(TARGETS rmlui EXPORT RmlUiTargets)
 
 
-
-else(NOT BUILD_FRAMEWORK)
-	#===================================
-	# Build combined Framework =========
-	#===================================
-
-	set(NAME RmlUi)
-
-	set(MASTER_PUB_HDR_FILES
-		${MASTER_Core_PUB_HDR_FILES}
-		${MASTER_Debugger_PUB_HDR_FILES}
-	)
-
-	add_library(${NAME}
-		${Core_HDR_FILES}
-		${MASTER_Core_PUB_HDR_FILES}
-		${Core_PUB_HDR_FILES}
-		${Core_SRC_FILES}
-		${Debugger_HDR_FILES}
-		${MASTER_Debugger_PUB_HDR_FILES}
-		${Debugger_PUB_HDR_FILES}
-		${Debugger_SRC_FILES}
-	)
-
-	set_target_properties(${NAME} PROPERTIES
-		VERSION ${PROJECT_VERSION}
-		SOVERSION ${PROJECT_VERSION_MAJOR}
-	)
-
-	set_property(SOURCE ${MASTER_PUB_HDR_FILES}
-		PROPERTY MACOSX_PACKAGE_LOCATION Headers
-	)
-	set_property(SOURCE ${Core_PUB_HDR_FILES}
-		PROPERTY MACOSX_PACKAGE_LOCATION Headers/Core
-	)
-	set_property(SOURCE ${Debugger_PUB_HDR_FILES}
-		PROPERTY MACOSX_PACKAGE_LOCATION Headers/Debugger
-	)
-	set_target_properties(${NAME} PROPERTIES
-		FRAMEWORK TRUE
-		FRAMEWORK_VERSION ${PROJECT_VERSION}
-		MACOSX_FRAMEWORK_IDENTIFIER com.rmlui.${NAME}
-		MACOSX_FRAMEWORK_SHORT_VERSION_STRING ${RMLUI_VERSION_SHORT}
-		MACOSX_FRAMEWORK_BUNDLE_VERSION ${PROJECT_VERSION}
-		XCODE_ATTRIBUTE_INSTALL_PATH "@rpath"
-		PUBLIC_HEADER ${MASTER_PUB_HDR_FILES}
-	)
-
-	install(TARGETS ${NAME}
-		EXPORT RmlUiTargets
-		LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-		ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-		RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-		FRAMEWORK DESTINATION Library/Frameworks
-	)
-
-	set(RMLUI_EXPORTED_TARGETS ${RMLUI_EXPORTED_TARGETS} ${NAME})
-endif(NOT BUILD_FRAMEWORK)
-
-
-# Build Lua bindings
-if(BUILD_LUA_BINDINGS)
-	set(NAME RmlLua)
-
-	add_library(${NAME} ${Lua_SRC_FILES}
-		${Lua_HDR_FILES}
-		${Lua_PUB_HDR_FILES}
-	)
-
-	set_target_properties(${NAME} PROPERTIES
-		VERSION ${PROJECT_VERSION}
-		SOVERSION ${PROJECT_VERSION_MAJOR}
-	)
-
-	add_common_target_options(${NAME})
-
-	install(TARGETS ${NAME}
-		EXPORT RmlUiTargets
-		LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-		ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-		RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+if(RMLUI_IS_ROOT_PROJECT)
+	# Skip installing any targets when RmlUi is included using `add_subdirectory`. Otherwise, if any of RmlUi's linked
+	# dependencies are not exported, then this results in errors about the dependency not being in any export set.
+	install(EXPORT RmlUiTargets
+		DESTINATION "${RMLUI_INSTALL_TARGETS_DIR}"
+		NAMESPACE RmlUi::
+		FILE RmlUiTargets.cmake
 	)
 	)
-
-	set(RMLUI_EXPORTED_TARGETS ${RMLUI_EXPORTED_TARGETS} ${NAME})
-endif()
-
-if(DISABLE_RTTI_AND_EXCEPTIONS)
-	if( CMAKE_COMPILER_IS_GNUCXX )
-		add_definitions( -fno-rtti -fno-exceptions )
-	elseif( MSVC )
-		add_definitions( -D_HAS_EXCEPTIONS=0 /GR- )
-		if(CMAKE_CXX_FLAGS MATCHES "/EHsc ")
-			string(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
-			message(STATUS "CMAKE_CXX_FLAGS matches /EHsc before end of string replaced...")
-		endif()
-
-		if(CMAKE_CXX_FLAGS MATCHES "/EHsc$")
-			string(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
-			message(STATUS "CMAKE_CXX_FLAGS matches /EHsc at end of string replaced...")
-		endif()
-	else()
-		message(STATUS "Could not create build configuration without rtti and exceptions...")
-	endif()
-endif()
-
-
-#===================================
-# Link libraries ===================
-#===================================
-
-if(NOT BUILD_FRAMEWORK)
-	target_include_directories(RmlCore PRIVATE ${CORE_INCLUDE_DIRS})
-	target_include_directories(RmlCore INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/Include> $<INSTALL_INTERFACE:include>)
-	target_link_libraries(RmlCore PRIVATE ${CORE_LINK_LIBS})
-	target_link_libraries(RmlCore PUBLIC ${CORE_PUBLIC_LINK_LIBS})
-	target_link_libraries(RmlDebugger RmlCore)
-	target_compile_definitions(RmlCore PRIVATE ${CORE_PRIVATE_DEFS})
-	target_compile_definitions(RmlCore PUBLIC ${CORE_PUBLIC_DEFS})
-else()
-	target_include_directories(RmlUi PRIVATE ${CORE_INCLUDE_DIRS})
-	target_link_libraries(RmlUi PRIVATE ${CORE_LINK_LIBS})
-	target_link_libraries(RmlUi PUBLIC ${CORE_PUBLIC_LINK_LIBS})
-	target_compile_definitions(RmlUi PRIVATE ${CORE_PRIVATE_DEFS})
-	target_compile_definitions(RmlUi PUBLIC ${CORE_PUBLIC_DEFS})
 endif()
 endif()
 
 
-if(BUILD_LUA_BINDINGS)
-	if(NOT BUILD_FRAMEWORK)
-		target_link_libraries(RmlLua RmlCore ${LUA_BINDINGS_LINK_LIBS})
-		target_include_directories(RmlLua PUBLIC ${LUA_BINDINGS_INCLUDE_DIRS})
-		target_compile_definitions(RmlLua PUBLIC ${LUA_BINDINGS_PUBLIC_DEFS})
-	else()
-		target_link_libraries(RmlUi ${LUA_BINDINGS_LINK_LIBS})
-		target_include_directories(RmlUi PUBLIC ${LUA_BINDINGS_INCLUDE_DIRS})
-		target_compile_definitions(RmlUi PUBLIC ${LUA_BINDINGS_PUBLIC_DEFS})
-	endif()
-endif()
-
-
-#===================================
-# Build samples ====================
-#===================================
-
-function(resource VAR SOURCE_PATH DESTINATION PATTERN)
-    file(GLOB_RECURSE _LIST CONFIGURE_DEPENDS ${SOURCE_PATH}/${PATTERN})
-    foreach (RESOURCE ${_LIST})
-        get_filename_component(_PARENT ${RESOURCE} DIRECTORY)
-        if (${_PARENT} STREQUAL ${SOURCE_PATH})
-            set(_DESTINATION ${DESTINATION})
-        else ()
-            file(RELATIVE_PATH _DESTINATION ${SOURCE_PATH} ${_PARENT})
-            set(_DESTINATION ${DESTINATION}/${_DESTINATION})
-        endif ()
-        set_property(SOURCE ${RESOURCE} PROPERTY MACOSX_PACKAGE_LOCATION ${_DESTINATION})
-    endforeach (RESOURCE)
-    set(${VAR} ${_LIST} PARENT_SCOPE)
-endfunction()
-
-# Build and link the samples
-macro(bl_sample NAME SAMPLE_SUB_DIR)
-	if (WIN32)
-		add_executable(${NAME} WIN32 ${${NAME}_SRC_FILES} ${${NAME}_HDR_FILES} )
-	elseif(APPLE)
-		resource(ASSETS ${SAMPLES_DIR}/assets Resources/assets *)
-		resource(DATA ${SAMPLES_DIR}/${SAMPLE_SUB_DIR}/data Resources/${SAMPLE_SUB_DIR}/data *)
-		resource(LUA ${SAMPLES_DIR}/${SAMPLE_SUB_DIR}/lua Resources/${SAMPLE_SUB_DIR}/lua *)
-
-		set(RESOURCE_FILES ${ASSETS} ${DATA} ${LUA})
-
-		add_executable(${NAME} MACOSX_BUNDLE ${${NAME}_SRC_FILES} ${${NAME}_HDR_FILES} ${RESOURCE_FILES})
-
-		# The first rpath is to the proper location where the framework/library SHOULD be, the second is to the location actually seen
-		# in the build environment
-		if(BUILD_FRAMEWORK)
-			set_target_properties(${NAME} PROPERTIES LINK_FLAGS "-rpath @executable_path/../Frameworks")
-		else()
-			set_target_properties(${NAME} PROPERTIES LINK_FLAGS "-rpath @executable_path/../lib")
-		endif()
-	else()
-		add_executable(${NAME} ${${NAME}_SRC_FILES} ${${NAME}_HDR_FILES} )
-	endif()
-
-	add_common_target_options(${NAME})
-
-	target_link_libraries(${NAME} ${ARGN})
-endmacro()
-
-# Build shell
-if(BUILD_SAMPLES OR BUILD_TESTING)
-	message("-- Adding shell with '${SAMPLES_BACKEND}' backend.")
-
-	include(SampleFileList)
-	include(BackendFileList)
-
-	if(NOT BUILD_FRAMEWORK)
-		set(sample_LIBRARIES
-			shell
-			RmlCore
-			RmlDebugger
-		)
-	else()
-		set(sample_LIBRARIES
-			shell
-			RmlUi
-		)
-	endif()
-
-	set(SAMPLES_DIR ${PROJECT_SOURCE_DIR}/Samples CACHE PATH "Path to samples directory.")
-	if(WIN32)
-		mark_as_advanced(SAMPLES_DIR)
-	endif()
-
-
-	set(BACKEND_SRC_FILES "${${SAMPLES_BACKEND}_SRC_FILES}")
-	set(BACKEND_HDR_FILES "${${SAMPLES_BACKEND}_HDR_FILES}")
-
-	if("${BACKEND_SRC_FILES}" STREQUAL "" OR "${BACKEND_HDR_FILES}" STREQUAL "")
-		message(FATAL_ERROR "Unknown samples backend '${SAMPLES_BACKEND}'.")
-	endif()
+install(DIRECTORY
+	"${CMAKE_CURRENT_SOURCE_DIR}/Include/RmlUi"
+	DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
+)
 
 
-	list(APPEND shell_SRC_FILES ${BACKEND_SRC_FILES})
-	list(APPEND shell_HDR_FILES ${BACKEND_HDR_FILES} ${BACKEND_COMMON_HDR_FILES})
+include(CMakePackageConfigHelpers)
 
 
-	add_library(shell STATIC ${shell_SRC_FILES} ${shell_HDR_FILES})
+configure_file(
+	"${CMAKE_CURRENT_SOURCE_DIR}/CMake/RmlUiConfig.cmake.in"
+	"${CMAKE_CURRENT_BINARY_DIR}/install/RmlUiConfig.cmake"
+	@ONLY
+)
+# RMLUI_CMAKE_MINIMUM_VERSION_RAISE_NOTICE:
+# From CMake 3.11 use compatibility mode `SameMinorVersion`.
+write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/install/RmlUiConfigVersion.cmake"
+	COMPATIBILITY ExactVersion
+)
+install(FILES
+	"${CMAKE_CURRENT_BINARY_DIR}/install/RmlUiConfig.cmake"
+	"${CMAKE_CURRENT_BINARY_DIR}/install/RmlUiConfigVersion.cmake"
+	"${CMAKE_CURRENT_SOURCE_DIR}/CMake/Dependencies.cmake"
+	DESTINATION
+	"${RMLUI_INSTALL_TARGETS_DIR}"
+)
+install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/CMake/Modules"
+	DESTINATION "${RMLUI_INSTALL_TARGETS_DIR}"
+)
 
 
-	target_include_directories(shell PUBLIC
-		${PROJECT_SOURCE_DIR}/Backends
-		${PROJECT_SOURCE_DIR}/Samples/shell/include
+if(RMLUI_IS_ROOT_PROJECT)
+	# Export build targets if RmlUi is the top-level project.
+	export(EXPORT RmlUiTargets
+		NAMESPACE RmlUi::
+		FILE RmlUiTargets.cmake
 	)
 	)
-
-	add_common_target_options(shell)
-	target_link_libraries(shell PUBLIC RmlCore RmlDebugger)
-
-	# Add OS dependencies.
-	if (WIN32)
-		target_link_libraries(shell PRIVATE shlwapi imm32)
-	elseif(APPLE)
-		target_link_libraries(shell PRIVATE "-framework Cocoa")
-	elseif(UNIX AND NOT APPLE AND NOT EMSCRIPTEN)
-		find_package(X11)
-		if (X11_FOUND)
-			message("-- Found X11 library.")
-			target_link_libraries(shell PRIVATE ${X11_LIBRARIES})
-			# Platform_X11 uses Xkb if possible instead of XGetKeyboardMapping for performance.
-			if(X11_Xkb_FOUND)
-				FIND_PACKAGE_MESSAGE(X11 "Found X11 KBlib: ${X11_X11_LIB}" "[${X11_X11_LIB}][${X11_XkbINCLUDE_DIR}]")
-				target_compile_definitions(shell PRIVATE HAS_X11XKBLIB)
-			endif()
-		endif()
-	endif()
-
-	# Add platform dependencies.
-	if(SAMPLES_BACKEND MATCHES "^X11")
-		if(NOT X11_FOUND)
-			message(FATAL_ERROR "X11 not found or not supported on this platform, select a different sample backend.")
-		endif()
-	endif()
-
-	if(SAMPLES_BACKEND MATCHES "^SDL")
-		message("-- Looking for SDL2 library for samples backend.")
-		if(EMSCRIPTEN)
-			set(EMSCRIPTEN_FLAGS "${EMSCRIPTEN_FLAGS} -sUSE_SDL=2 -sUSE_SDL_IMAGE=2 -sSDL2_IMAGE_FORMATS='[tga]'")
-		else()
-			find_package(SDL2 REQUIRED)
-
-			if(NOT SDL2_FOUND)
-				message(FATAL_ERROR "SDL2 not found")
-			endif()
-
-			if(SAMPLES_BACKEND STREQUAL "SDL_GL2")
-				find_package(GLEW REQUIRED)
-				if(NOT GLEW_FOUND)
-					message(FATAL_ERROR "GLEW not found")
-				endif()
-			endif()
-
-			# Check version requirement for the SDL renderer.
-			if(SAMPLES_BACKEND STREQUAL "SDL_SDLrenderer" AND "${SDL2_VERSION}" VERSION_LESS "2.0.20")
-				message(FATAL_ERROR "SDL2 native renderer backend (${SAMPLES_BACKEND}) requires SDL 2.0.20 (found ${SDL2_VERSION}).")
-			endif()
-
-			if(SAMPLES_BACKEND STREQUAL "SDL_GL2" OR SAMPLES_BACKEND STREQUAL "SDL_GL3" OR SAMPLES_BACKEND STREQUAL "SDL_SDLrenderer")
-				find_package(SDL2_image REQUIRED)
-				if(NOT SDL2_IMAGE_FOUND)
-					message(FATAL_ERROR "SDL2_image not found")
-				endif()
-			endif()
-
-			target_include_directories(shell PRIVATE ${SDL2_INCLUDE_DIR} ${SDL2_IMAGE_INCLUDE_DIR} ${GLEW_INCLUDE_DIR})
-			target_link_libraries(shell PRIVATE ${SDL2_LIBRARY} ${SDL2_IMAGE_LIBRARY} ${GLEW_LIBRARIES})
-		endif()
-	endif()
-
-	if(SAMPLES_BACKEND MATCHES "^SFML")
-		message("-- Looking for SFML 2.x library for samples backend.")
-		if (WIN32)
-			find_package(SFML 2 REQUIRED COMPONENTS graphics window system main)
-		else()
-			find_package(SFML 2 REQUIRED COMPONENTS graphics window system)
-		endif()
-		target_include_directories(shell PRIVATE ${SFML_INCLUDE_DIR})
-		target_link_libraries(shell PRIVATE ${SFML_LIBRARIES})
-	endif()
-
-	if(SAMPLES_BACKEND MATCHES "GLFW")
-		message("-- Looking for GLFW3 library for samples backend.")
-		find_package(glfw3 3.3 CONFIG REQUIRED)
-		target_link_libraries(shell PRIVATE glfw)
-		message("-- Found GLFW version ${glfw3_VERSION}.")
-	endif()
-
-	# Add renderer dependencies.
-	if(SAMPLES_BACKEND MATCHES "GL2$")
-		message("-- Adding OpenGL 2 renderer backend.")
-		find_package(OpenGL REQUIRED)
-		target_include_directories(shell PRIVATE ${OPENGL_INCLUDE_DIR})
-		target_link_libraries(shell PRIVATE ${OPENGL_LIBRARIES})
-		target_compile_definitions(shell PRIVATE RMLUI_RENDERER_GL2)
-		if(APPLE)
-			target_compile_definitions(shell PRIVATE GL_SILENCE_DEPRECATION)
-		endif()
-	endif()
-
-	if(SAMPLES_BACKEND MATCHES "VK$")
-		message("-- Using Vulkan renderer backend.")
-
-		option(RMLUI_VK_DEBUG "Enable debugging mode for Vulkan renderer." OFF)
-		mark_as_advanced(RMLUI_VK_DEBUG)
-		if(RMLUI_VK_DEBUG)
-			target_compile_definitions(shell PRIVATE RMLUI_VK_DEBUG)
-		endif()
-
-		target_link_libraries(shell PRIVATE ${CMAKE_DL_LIBS})
-	endif()
-
-	if(SAMPLES_BACKEND MATCHES "GL3$")
-		message("-- Adding OpenGL 3 renderer backend.")
-		if(EMSCRIPTEN)
-			set(EMSCRIPTEN_EXE_FLAGS "${EMSCRIPTEN_EXE_FLAGS} -sMIN_WEBGL_VERSION=2 -sMAX_WEBGL_VERSION=2")
-		else()
-			find_package(OpenGL REQUIRED)
-			target_include_directories(shell PRIVATE ${OPENGL_INCLUDE_DIR})
-			target_link_libraries(shell PRIVATE ${OPENGL_LIBRARIES} ${CMAKE_DL_LIBS})
-			target_compile_definitions(shell PRIVATE RMLUI_RENDERER_GL3)
-			if(APPLE)
-				target_compile_definitions(shell PRIVATE GL_SILENCE_DEPRECATION)
-			endif()
-		endif()
-	endif()
-endif()
-
-
-if(BUILD_SAMPLES)
-	set(samples treeview customlog drag loaddocument transform bitmapfont animation benchmark demo databinding effects)
-	set(tutorials template drag)
-
-	if(ENABLE_LOTTIE_PLUGIN)
-		list(APPEND samples "lottie")
-	endif()
-	if(ENABLE_SVG_PLUGIN)
-		list(APPEND samples "svg")
-	endif()
-	if(ENABLE_HARFBUZZ)
-		list(APPEND samples "harfbuzzshaping")
-	endif()
-
-	# Build and install the basic samples
-	foreach(sample ${samples})
-		bl_sample(${sample} basic/${sample} ${sample_LIBRARIES} )
-
-		# The samples always set this as their current working directory
-		install(DIRECTORY DESTINATION ${SAMPLES_DIR}/basic/${sample})
-		install(TARGETS ${sample}
-			RUNTIME DESTINATION ${SAMPLES_DIR}/${sample}
-			BUNDLE DESTINATION ${SAMPLES_DIR})
-	endforeach()
-
-	# Build and install the tutorials
-	foreach(tutorial ${tutorials})
-		set(tutorial_fullname tutorial_${tutorial})
-		bl_sample(${tutorial_fullname} tutorial/${tutorial} ${sample_LIBRARIES})
-
-		# The tutorials always set this as their current working directory
-		install(DIRECTORY DESTINATION ${SAMPLES_DIR}/tutorial/${tutorial})
-		install(TARGETS ${tutorial_fullname}
-			RUNTIME DESTINATION ${SAMPLES_DIR}/${tutorial}
-			BUNDLE DESTINATION ${SAMPLES_DIR})
-	endforeach()
-
-	# Build and install invaders sample
-	bl_sample(invaders invaders  ${sample_LIBRARIES})
-	install(DIRECTORY DESTINATION ${SAMPLES_DIR}/invaders)
-	install(TARGETS invaders
-		RUNTIME DESTINATION ${SAMPLES_DIR}/invaders
-		BUNDLE DESTINATION ${SAMPLES_DIR})
-
-	if(BUILD_LUA_BINDINGS)
-		bl_sample(luainvaders luainvaders RmlLua ${sample_LIBRARIES} ${LUA_BINDINGS_LINK_LIBS})
-		install(DIRECTORY DESTINATION ${SAMPLES_DIR}/luainvaders)
-		install(TARGETS luainvaders
-			RUNTIME DESTINATION ${SAMPLES_DIR}/luainvaders
-			BUNDLE DESTINATION ${SAMPLES_DIR})
-	endif()
-
-	# Attach harfbuzz sample dependencies to samples
-	if (ENABLE_HARFBUZZ)
-		target_include_directories(harfbuzzshaping PRIVATE ${FREETYPE_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}/Source/Core)
-		target_link_libraries(harfbuzzshaping harfbuzz::harfbuzz)
-	endif()
-
-	# Add assets to emscripten binaries
-	if(EMSCRIPTEN)
-		message("-- Preloading emscripten sample assets")
-
-		set(COMMON_ASSET_FOLDER "Samples/assets/")
-		set(EMSCRIPTEN_EXE_FLAGS "${EMSCRIPTEN_EXE_FLAGS} --preload-file ${CMAKE_CURRENT_SOURCE_DIR}/${COMMON_ASSET_FOLDER}@/${COMMON_ASSET_FOLDER}")
-		file(GLOB COMMON_ASSET_FILES "${COMMON_ASSET_FOLDER}*")
-
-		foreach(sample ${samples})
-			set(SAMPLE_DATA_FOLDER "Samples/basic/${sample}/data/")
-			set(ABS_SAMPLE_DATA_FOLDER "${CMAKE_CURRENT_SOURCE_DIR}/${SAMPLE_DATA_FOLDER}")
-			if(EXISTS ${ABS_SAMPLE_DATA_FOLDER})
-				target_link_libraries(${sample} "--preload-file ${ABS_SAMPLE_DATA_FOLDER}@/${SAMPLE_DATA_FOLDER}")
-			endif()
-			file(GLOB SAMPLE_DATA_FILES "${SAMPLE_DATA_FOLDER}*")
-			set_target_properties(${sample} PROPERTIES LINK_DEPENDS "${COMMON_ASSET_FILES};${SAMPLE_DATA_FILES}")
-		endforeach()
-
-		foreach(tutorial ${tutorials})
-			set(TUTORIAL_DATA_FOLDER "Samples/tutorial/${tutorial}/data/")
-			set(ABS_TUTORIAL_DATA_FOLDER "${CMAKE_CURRENT_SOURCE_DIR}/${TUTORIAL_DATA_FOLDER}")
-			if(EXISTS ${ABS_TUTORIAL_DATA_FOLDER})
-				target_link_libraries("tutorial_${tutorial}" "--preload-file ${ABS_TUTORIAL_DATA_FOLDER}@/${TUTORIAL_DATA_FOLDER}")
-			endif()
-			file(GLOB TUTORIAL_DATA_FILES "${TUTORIAL_DATA_FOLDER}*")
-			set_target_properties(${sample} PROPERTIES LINK_DEPENDS "${COMMON_ASSET_FILES};${TUTORIAL_DATA_FILES}")
-		endforeach()
-
-		set(INVADERS_DATA_FOLDER "Samples/invaders/data/")
-		target_link_libraries(invaders "-sALLOW_MEMORY_GROWTH --preload-file ${CMAKE_CURRENT_SOURCE_DIR}/${INVADERS_DATA_FOLDER}@/${INVADERS_DATA_FOLDER}")
-		file(GLOB INVADERS_DATA_FILES "${INVADERS_DATA_FOLDER}*")
-		set_target_properties(invaders PROPERTIES LINK_DEPENDS "${COMMON_ASSET_FILES};${INVADERS_DATA_FILES}")
-	endif()
-endif()
-
-#===================================
-# Source grouping for IDEs =========
-#===================================
-
-source_group("Core\\Layout" REGULAR_EXPRESSION "/Core/Layout/")
-source_group("Core\\Elements" REGULAR_EXPRESSION "/Core/Elements/")
-source_group("Core\\FontEngineDefault" REGULAR_EXPRESSION "/Core/FontEngineDefault/")
-
-#===================================
-# Add global options ===============
-#===================================
-
-if(EMSCRIPTEN)
-	# Enables Asyncify which we only need since the backend doesn't control the main loop. This enables us to yield to the browser during the backend call to
-	# Backend::ProcessEvents(). Asyncify results in larger and slower code, users are instead encouraged to use 'emscripten_set_main_loop()' and family.
-	set(EMSCRIPTEN_EXE_FLAGS "${EMSCRIPTEN_EXE_FLAGS} -sASYNCIFY")
-
-	message(STATUS "Compiling for Emscripten.\n\t- Flags:${EMSCRIPTEN_FLAGS}\n\t- ExeFlags:${EMSCRIPTEN_EXE_FLAGS}")
-	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EMSCRIPTEN_FLAGS}")
-	set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EMSCRIPTEN_FLAGS}")
-	set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${EMSCRIPTEN_FLAGS} ${EMSCRIPTEN_EXE_FLAGS}")
-	set(CMAKE_EXECUTABLE_SUFFIX .html)
-endif()
-
-#===================================
-# Add tests ========================
-#===================================
-
-if(RMLUI_TESTS_ENABLED)
-	add_subdirectory(Tests)
 endif()
 endif()
 
 
-#===================================
-# Installation =====================
-#===================================
-
-if(BUILD_LUA_BINDINGS)
-	install(DIRECTORY ${PROJECT_SOURCE_DIR}/Include/RmlUi
-			DESTINATION include
-	)
-else()
-	install(DIRECTORY ${PROJECT_SOURCE_DIR}/Include/RmlUi
-			DESTINATION include
-			PATTERN "Lua" EXCLUDE
-	)
+include("CMake/PackageUtilities.cmake")
+if(RMLUI_INSTALL_LICENSES_AND_BUILD_INFO)
+	install_licenses()
+	install_build_info()
 endif()
 endif()
-
-if(BUILD_SAMPLES)
-	install(DIRECTORY ${PROJECT_SOURCE_DIR}/Samples/assets
-			DESTINATION ${SAMPLES_DIR}
-	)
-
-	install(DIRECTORY ${PROJECT_SOURCE_DIR}/Samples/tutorial/template/data
-			DESTINATION ${SAMPLES_DIR}/tutorial/template
-	)
-	install(DIRECTORY ${PROJECT_SOURCE_DIR}/Samples/tutorial/drag/data
-			DESTINATION ${SAMPLES_DIR}/tutorial/drag
-	)
-	install(DIRECTORY ${PROJECT_SOURCE_DIR}/Samples/basic/animation/data
-			DESTINATION ${SAMPLES_DIR}/basic/animation
-	)
-	install(DIRECTORY ${PROJECT_SOURCE_DIR}/Samples/basic/benchmark/data
-			DESTINATION ${SAMPLES_DIR}/basic/benchmark
-	)
-	install(DIRECTORY ${PROJECT_SOURCE_DIR}/Samples/basic/bitmapfont/data
-			DESTINATION ${SAMPLES_DIR}/basic/bitmapfont
-	)
-	install(DIRECTORY ${PROJECT_SOURCE_DIR}/Samples/basic/databinding/data
-			DESTINATION ${SAMPLES_DIR}/basic/databinding
-	)
-	install(DIRECTORY ${PROJECT_SOURCE_DIR}/Samples/basic/demo/data
-			DESTINATION ${SAMPLES_DIR}/basic/demo
-	)
-	install(DIRECTORY ${PROJECT_SOURCE_DIR}/Samples/basic/effects/data
-			DESTINATION ${SAMPLES_DIR}/basic/effects
-	)
-	install(DIRECTORY ${PROJECT_SOURCE_DIR}/Samples/basic/transform/data
-			DESTINATION ${SAMPLES_DIR}/basic/transform
-	)
-	install(DIRECTORY ${PROJECT_SOURCE_DIR}/Samples/basic/treeview/data
-			DESTINATION ${SAMPLES_DIR}/basic/treeview
-	)
-	install(DIRECTORY ${PROJECT_SOURCE_DIR}/Samples/basic/drag/data
-			DESTINATION ${SAMPLES_DIR}/basic/drag
-	)
-	install(DIRECTORY ${PROJECT_SOURCE_DIR}/Samples/invaders/data
-			DESTINATION ${SAMPLES_DIR}/invaders
-	)
-
-	if (ENABLE_HARFBUZZ AND HARFBUZZ_FOUND)
-		install(DIRECTORY ${PROJECT_SOURCE_DIR}/Samples/basic/harfbuzzshaping/data
-			DESTINATION ${SAMPLES_DIR}/basic/harfbuzzshaping
-		)
-	endif()
-
-	if(TARGET lottie)
-		install(DIRECTORY ${PROJECT_SOURCE_DIR}/Samples/basic/lottie/data
-				DESTINATION ${SAMPLES_DIR}/basic/lottie
-		)
-	endif()
-	if(TARGET svg)
-		install(DIRECTORY ${PROJECT_SOURCE_DIR}/Samples/basic/svg/data
-				DESTINATION ${SAMPLES_DIR}/basic/svg
-		)
-	endif()
-
-	if(BUILD_LUA_BINDINGS)
-		install(DIRECTORY ${PROJECT_SOURCE_DIR}/Samples/luainvaders/data
-				DESTINATION ${SAMPLES_DIR}/luainvaders
-		)
-		install(DIRECTORY ${PROJECT_SOURCE_DIR}/Samples/luainvaders/lua
-				DESTINATION ${SAMPLES_DIR}/luainvaders
-		)
-	endif()
+if(RMLUI_INSTALL_DEPENDENCIES_DIR)
+	install_vcpkg_dependencies()
 endif()
 endif()
 
 
-#===================================
-# Generate Config.cmake files ======
-#===================================
-
-# Try to include helper module
-include(CMakePackageConfigHelpers OPTIONAL RESULT_VARIABLE PkgHelpers_AVAILABLE)
-
-# guard against older versions of cmake which do not provide it
-if(${CMAKE_PROJECT_NAME} STREQUAL ${PROJECT_NAME})
-if(PkgHelpers_AVAILABLE)
-	set (INCLUDE_INSTALL_DIR "include")
-	set (LIB_INSTALL_DIR "lib")
-	set (INCLUDE_DIR "${PROJECT_SOURCE_DIR}/Include")
-
-	# generate configuration for install tree
-	configure_package_config_file(${PROJECT_SOURCE_DIR}/CMake/RmlUiConfig.cmake.install.in
-		${CMAKE_CURRENT_BINARY_DIR}/install/RmlUiConfig.cmake
-		INSTALL_DESTINATION ${LIB_INSTALL_DIR}/RmlUi/cmake
-		PATH_VARS INCLUDE_INSTALL_DIR LIB_INSTALL_DIR)
-	write_basic_package_version_file(
-		${CMAKE_CURRENT_BINARY_DIR}/install/RmlUiConfigVersion.cmake
-		VERSION ${PROJECT_VERSION}
-		COMPATIBILITY SameMajorVersion )
-	install(FILES ${CMAKE_CURRENT_BINARY_DIR}/install/RmlUiConfig.cmake
-		${CMAKE_CURRENT_BINARY_DIR}/install/RmlUiConfigVersion.cmake
-		DESTINATION ${LIB_INSTALL_DIR}/RmlUi/cmake )
-	install(EXPORT RmlUiTargets
-		DESTINATION ${LIB_INSTALL_DIR}/RmlUi/cmake)
-
-	# generate configuration for build tree
-	configure_package_config_file(${PROJECT_SOURCE_DIR}/CMake/RmlUiConfig.cmake.build.in
-		${CMAKE_CURRENT_BINARY_DIR}/RmlUiConfig.cmake
-		INSTALL_DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
-		PATH_VARS INCLUDE_DIR CMAKE_CURRENT_BINARY_DIR)
-	if(NOT ${CMAKE_PROJECT_NAME} STREQUAL ${PROJECT_NAME})
-		export(TARGETS ${RMLUI_EXPORTED_TARGETS}
-			FILE "${CMAKE_CURRENT_BINARY_DIR}/RmlUiTargets.cmake")
-	endif()
-	write_basic_package_version_file(
-		${CMAKE_CURRENT_BINARY_DIR}/RmlUiConfigVersion.cmake
-		VERSION ${PROJECT_VERSION}
-		COMPATIBILITY SameMajorVersion )
-	set(RmlUi_DIR "${CMAKE_CURRENT_BINARY_DIR}" CACHE PATH "The directory containing a CMake configuration file for RmlUi.")
-else()
-	message("If you wish to use find_package(RmlUi) in your own project to find RmlUi library"
-		" please update cmake to version which provides CMakePackageConfighelpers module"
-		" or write generators for RmlUiConfig.cmake by yourself.")
-endif()
-endif()
+install_runtime_dependencies()

+ 58 - 0
CMakePresets.json

@@ -0,0 +1,58 @@
+{
+	"version": 3,
+	"configurePresets": [
+		{
+			"name": "samples",
+			"description": "Enable samples but only those without extra dependencies.",
+			"cacheVariables": {
+				"RMLUI_SAMPLES": true
+			}
+		},
+		{
+			"name": "samples-all",
+			"description": "Enable all samples, also those with extra dependencies.",
+			"inherits": "samples",
+			"cacheVariables": {
+				"RMLUI_HARFBUZZ_SAMPLE": true,
+				"RMLUI_LOTTIE_PLUGIN": true,
+				"RMLUI_SVG_PLUGIN": true,
+				"RMLUI_LUA_BINDINGS": true
+			}
+		},
+		{
+			"name": "standalone",
+			"description": "Build the library completely without any dependencies, features the `bitmapfont` sample.",
+			"cacheVariables": {
+				"RMLUI_SAMPLES": true,
+				"RMLUI_FONT_ENGINE": "none",
+				"RMLUI_BACKEND": "native"
+			}
+		},
+		{
+			"name": "dev",
+			"description": "Enable testing in addition to samples.",
+			"installDir": "Install",
+			"cacheVariables": {
+				"RMLUI_SAMPLES": true,
+				"BUILD_TESTING": true
+			},
+			"warnings": {
+				"dev": true
+			},
+			"errors": {
+				"dev": true
+			}
+		},
+		{
+			"name": "dev-all",
+			"description": "Enable testing in addition to samples, including those that require extra dependencies.",
+			"inherits": "dev",
+			"cacheVariables": {
+				"RMLUI_HARFBUZZ_SAMPLE": true,
+				"RMLUI_LOTTIE_PLUGIN": true,
+				"RMLUI_SVG_PLUGIN": true,
+				"RMLUI_LUA_BINDINGS": true
+			}
+		}
+	]
+}

+ 0 - 0
Dependencies/empty.txt


+ 0 - 65
Dependencies/osx-depends.sh

@@ -1,65 +0,0 @@
-#!/usr/bin/env sh
-
-BUILD_FREETYPE2=YES
-BUILD_LUA=YES
-BUILD_PLATFORM=osx
-
-
-#Get depends root directory
-
-pushd `dirname $0` > /dev/null
-SCRIPT_PATH=`pwd`
-popd > /dev/null
-
-DEPS_DIR=${SCRIPT_PATH}
-
-BUILD_OUTPUTDIR=${DEPS_DIR}/${BUILD_PLATFORM}
-
-if [ ! -d "${BUILD_OUTPUTDIR}" ]; then
-	mkdir "${BUILD_OUTPUTDIR}"
-fi
-if [ ! -d "${BUILD_OUTPUTDIR}/lib" ]; then
-	mkdir "${BUILD_OUTPUTDIR}/lib"
-fi
-if [ ! -d "${BUILD_OUTPUTDIR}/include" ]; then
-	mkdir "${BUILD_OUTPUTDIR}/include"
-fi
-
-create_ios_outdir_lipo()
-{
-        for lib_i386 in `find $LOCAL_OUTDIR/i386 -name "lib*.a"`; do
-                lib_arm7=`echo $lib_i386 | sed "s/i386/arm7/g"`
-                lib_arm7s=`echo $lib_i386 | sed "s/i386/arm7s/g"`
-                lib=`echo $lib_i386 | sed "s/i386//g"`
-                xcrun -sdk iphoneos lipo -arch armv7s $lib_arm7s -arch armv7 $lib_arm7 -create -output $lib
-        done
-}
-
-build_freetype()
-{
-
-	cd "${DEPS_DIR}"
-	if [ ! -d "freetype2" ]; then
-		git clone --recursive git://git.sv.nongnu.org/freetype/freetype2.git freetype2
-	fi
-
-	cd freetype2
-
-	cmake CMakeLists.txt -DBUILD_SHARED_LIBS:BOOL=false
-	make
-
-	cmake CMakeLists.txt -DBUILD_SHARED_LIBS:BOOL=true
-	make
-
-	if [ ! -d "${BUILD_OUTPUTDIR}/include/freetype2" ]; then
-		mkdir "${BUILD_OUTPUTDIR}/include/freetype2"
-	fi
-	cp -Rp include/* "${BUILD_OUTPUTDIR}/include/freetype2/"
-	cp libfreetype.a "${BUILD_OUTPUTDIR}/lib/"
-	cp libfreetype.dylib "${BUILD_OUTPUTDIR}/lib/"
-
-	cd "${DEPS_DIR}"
-}
-
-
-build_freetype

+ 1 - 1
Include/RmlUi/Core/Header.h

@@ -36,7 +36,7 @@
 
 
 #if !defined RMLUI_STATIC_LIB
 #if !defined RMLUI_STATIC_LIB
 	#if defined RMLUI_PLATFORM_WIN32
 	#if defined RMLUI_PLATFORM_WIN32
-		#if defined RmlCore_EXPORTS
+		#if defined RMLUI_CORE_EXPORTS
 			#define RMLUICORE_API __declspec(dllexport)
 			#define RMLUICORE_API __declspec(dllexport)
 			// Note: Changing a RMLUICORE_API_INLINE method
 			// Note: Changing a RMLUICORE_API_INLINE method
 			// breaks ABI compatibility!!
 			// breaks ABI compatibility!!

+ 2 - 2
Include/RmlUi/Core/Traits.h

@@ -95,7 +95,7 @@ public:
 
 
 } // namespace Rml
 } // namespace Rml
 
 
-#ifdef RMLUI_USE_CUSTOM_RTTI
+#ifdef RMLUI_CUSTOM_RTTI
 
 
 	#define RMLUI_RTTI_Define(_NAME_)                             \
 	#define RMLUI_RTTI_Define(_NAME_)                             \
 		using RttiClassType = _NAME_;                             \
 		using RttiClassType = _NAME_;                             \
@@ -190,6 +190,6 @@ const char* rmlui_type_name()
 	return typeid(T).name();
 	return typeid(T).name();
 }
 }
 
 
-#endif // RMLUI_USE_CUSTOM_RTTI
+#endif // RMLUI_CUSTOM_RTTI
 
 
 #endif // RMLUI_CORE_TRAITS_H
 #endif // RMLUI_CORE_TRAITS_H

+ 1 - 1
Include/RmlUi/Debugger/Header.h

@@ -33,7 +33,7 @@
 
 
 #if !defined RMLUI_STATIC_LIB
 #if !defined RMLUI_STATIC_LIB
 	#ifdef RMLUI_PLATFORM_WIN32
 	#ifdef RMLUI_PLATFORM_WIN32
-		#ifdef RmlDebugger_EXPORTS
+		#ifdef RMLUI_DEBUGGER_EXPORTS
 			#define RMLUIDEBUGGER_API __declspec(dllexport)
 			#define RMLUIDEBUGGER_API __declspec(dllexport)
 		#else
 		#else
 			#define RMLUIDEBUGGER_API __declspec(dllimport)
 			#define RMLUIDEBUGGER_API __declspec(dllimport)

+ 1 - 1
Include/RmlUi/Lua/Header.h

@@ -37,7 +37,7 @@
 
 
 #if !defined RMLUI_STATIC_LIB
 #if !defined RMLUI_STATIC_LIB
 	#ifdef RMLUI_PLATFORM_WIN32
 	#ifdef RMLUI_PLATFORM_WIN32
-		#if defined RmlLua_EXPORTS
+		#if defined RMLUI_LUA_EXPORTS
 			#define RMLUILUA_API __declspec(dllexport)
 			#define RMLUILUA_API __declspec(dllexport)
 		#else
 		#else
 			#define RMLUILUA_API __declspec(dllimport)
 			#define RMLUILUA_API __declspec(dllimport)

+ 2 - 2
Include/RmlUi/Lua/IncludeLua.h

@@ -29,7 +29,7 @@
 #ifndef RMLUI_LUA_INCLUDELUA_H
 #ifndef RMLUI_LUA_INCLUDELUA_H
 #define RMLUI_LUA_INCLUDELUA_H
 #define RMLUI_LUA_INCLUDELUA_H
 
 
-#ifndef RMLUI_LUA_COMPILED_AS_CXX
+#ifndef RMLUI_LUA_AS_CXX
 extern "C" {
 extern "C" {
 #endif
 #endif
 
 
@@ -38,7 +38,7 @@ extern "C" {
 #include <lua.h>
 #include <lua.h>
 #include <lualib.h>
 #include <lualib.h>
 
 
-#ifndef RMLUI_LUA_COMPILED_AS_CXX
+#ifndef RMLUI_LUA_AS_CXX
 }
 }
 #endif
 #endif
 
 

+ 35 - 0
Samples/CMakeLists.txt

@@ -0,0 +1,35 @@
+set(RMLUI_SAMPLE_PREFIX "rmlui_sample_")
+
+if(RMLUI_BACKEND MATCHES "VK$")
+	option(RMLUI_VK_DEBUG "Enable debugging mode for Vulkan renderer." OFF)
+	mark_as_advanced(RMLUI_VK_DEBUG)
+	if(RMLUI_VK_DEBUG)
+		target_compile_definitions(rmlui_backend_${RMLUI_BACKEND} INTERFACE "RMLUI_VK_DEBUG")
+	endif()
+endif()
+
+if(RMLUI_SHELL)
+	include("${PROJECT_SOURCE_DIR}/CMake/DependenciesForShell.cmake")
+	add_subdirectory("shell")
+endif()
+
+if(RMLUI_SAMPLES)
+	if(NOT RMLUI_FONT_ENGINE_ENABLED)
+		message(NOTICE "Building samples without any font engine selected - most samples will be disabled.")
+	endif()
+
+	add_subdirectory("basic")
+
+	if(RMLUI_FONT_ENGINE_ENABLED)
+		add_subdirectory("invaders")
+		add_subdirectory("tutorial")
+	endif()
+	if(RMLUI_FONT_ENGINE_ENABLED AND RMLUI_LUA_BINDINGS)
+		add_subdirectory("luainvaders")
+	endif()
+
+	install(DIRECTORY assets shell
+		DESTINATION "${CMAKE_INSTALL_DATADIR}/Samples"
+		PATTERN "CMakeLists.txt" EXCLUDE
+	)
+endif()

+ 32 - 0
Samples/basic/CMakeLists.txt

@@ -0,0 +1,32 @@
+# The following sample does not require any default font engine.
+add_subdirectory("bitmapfont")
+
+# Only enable the remaining samples if a default font engine is selected.
+if(RMLUI_FONT_ENGINE_ENABLED)
+	add_subdirectory("animation")
+	add_subdirectory("benchmark")
+	add_subdirectory("customlog")
+	add_subdirectory("databinding")
+	add_subdirectory("demo")
+	add_subdirectory("drag")
+	add_subdirectory("effects")
+	add_subdirectory("loaddocument")
+	add_subdirectory("transform")
+	add_subdirectory("treeview")
+
+	if(RMLUI_HARFBUZZ_SAMPLE)
+		add_subdirectory("harfbuzz")
+	else()
+		message(STATUS "Harfbuzz sample disabled due to RMLUI_HARFBUZZ_SAMPLE=OFF")
+	endif()
+	if(RMLUI_LOTTIE_PLUGIN)
+		add_subdirectory("lottie")
+	else()
+		message(STATUS "Lottie sample disabled due to RMLUI_LOTTIE_PLUGIN=OFF")
+	endif()
+	if(RMLUI_SVG_PLUGIN)
+		add_subdirectory("svg")
+	else()
+		message(STATUS "SVG sample disabled due to RMLUI_SVG_PLUGIN=OFF")
+	endif()
+endif()

+ 12 - 0
Samples/basic/animation/CMakeLists.txt

@@ -0,0 +1,12 @@
+set(SAMPLE_NAME "animation")
+set(TARGET_NAME "${RMLUI_SAMPLE_PREFIX}${SAMPLE_NAME}")
+
+add_executable(${TARGET_NAME} WIN32
+	src/main.cpp
+)
+
+set_common_target_options(${TARGET_NAME})
+
+target_link_libraries(${TARGET_NAME} PRIVATE rmlui_shell)
+
+install_sample_target(${TARGET_NAME})

+ 12 - 0
Samples/basic/benchmark/CMakeLists.txt

@@ -0,0 +1,12 @@
+set(SAMPLE_NAME "benchmark")
+set(TARGET_NAME "${RMLUI_SAMPLE_PREFIX}${SAMPLE_NAME}")
+
+add_executable(${TARGET_NAME} WIN32
+	src/main.cpp
+)
+
+set_common_target_options(${TARGET_NAME})
+
+target_link_libraries(${TARGET_NAME} PRIVATE rmlui_shell)
+
+install_sample_target(${TARGET_NAME})

+ 16 - 0
Samples/basic/bitmapfont/CMakeLists.txt

@@ -0,0 +1,16 @@
+set(SAMPLE_NAME "bitmapfont")
+set(TARGET_NAME "${RMLUI_SAMPLE_PREFIX}${SAMPLE_NAME}")
+
+add_executable(${TARGET_NAME} WIN32
+	src/FontEngineBitmap.cpp
+	src/FontEngineBitmap.h
+	src/FontEngineInterfaceBitmap.cpp
+	src/FontEngineInterfaceBitmap.h
+	src/main.cpp
+)
+
+set_common_target_options(${TARGET_NAME})
+
+target_link_libraries(${TARGET_NAME} PRIVATE rmlui_shell)
+
+install_sample_target(${TARGET_NAME})

+ 14 - 0
Samples/basic/customlog/CMakeLists.txt

@@ -0,0 +1,14 @@
+set(SAMPLE_NAME "customlog")
+set(TARGET_NAME "${RMLUI_SAMPLE_PREFIX}${SAMPLE_NAME}")
+
+add_executable(${TARGET_NAME} WIN32
+	src/main.cpp
+	src/SystemInterface.cpp
+	src/SystemInterface.h
+)
+
+set_common_target_options(${TARGET_NAME})
+
+target_link_libraries(${TARGET_NAME} PRIVATE rmlui_shell)
+
+install_sample_target(${TARGET_NAME})

+ 12 - 0
Samples/basic/databinding/CMakeLists.txt

@@ -0,0 +1,12 @@
+set(SAMPLE_NAME "databinding")
+set(TARGET_NAME "${RMLUI_SAMPLE_PREFIX}${SAMPLE_NAME}")
+
+add_executable(${TARGET_NAME} WIN32
+	src/main.cpp
+)
+
+set_common_target_options(${TARGET_NAME})
+
+target_link_libraries(${TARGET_NAME} PRIVATE rmlui_shell)
+
+install_sample_target(${TARGET_NAME})

+ 12 - 0
Samples/basic/demo/CMakeLists.txt

@@ -0,0 +1,12 @@
+set(SAMPLE_NAME "demo")
+set(TARGET_NAME "${RMLUI_SAMPLE_PREFIX}${SAMPLE_NAME}")
+
+add_executable(${TARGET_NAME} WIN32
+	src/main.cpp
+)
+
+set_common_target_options(${TARGET_NAME})
+
+target_link_libraries(${TARGET_NAME} PRIVATE rmlui_shell)
+
+install_sample_target(${TARGET_NAME})

+ 16 - 0
Samples/basic/drag/CMakeLists.txt

@@ -0,0 +1,16 @@
+set(SAMPLE_NAME "drag")
+set(TARGET_NAME "${RMLUI_SAMPLE_PREFIX}${SAMPLE_NAME}")
+
+add_executable(${TARGET_NAME} WIN32
+	src/DragListener.cpp
+	src/DragListener.h
+	src/Inventory.cpp
+	src/Inventory.h
+	src/main.cpp
+)
+
+set_common_target_options(${TARGET_NAME})
+
+target_link_libraries(${TARGET_NAME} PRIVATE rmlui_shell)
+
+install_sample_target(${TARGET_NAME})

+ 12 - 0
Samples/basic/effects/CMakeLists.txt

@@ -0,0 +1,12 @@
+set(SAMPLE_NAME "effects")
+set(TARGET_NAME "${RMLUI_SAMPLE_PREFIX}${SAMPLE_NAME}")
+
+add_executable(${TARGET_NAME} WIN32
+	src/main.cpp
+)
+
+set_common_target_options(${TARGET_NAME})
+
+target_link_libraries(${TARGET_NAME} PRIVATE rmlui_shell)
+
+install_sample_target(${TARGET_NAME})

+ 35 - 0
Samples/basic/harfbuzz/CMakeLists.txt

@@ -0,0 +1,35 @@
+set(SAMPLE_NAME "harfbuzz")
+set(TARGET_NAME "${RMLUI_SAMPLE_PREFIX}${SAMPLE_NAME}")
+
+add_executable(${TARGET_NAME} WIN32
+	src/FontEngineInterfaceHarfBuzz.cpp
+	src/FontEngineInterfaceHarfBuzz.h
+	src/FontFace.cpp
+	src/FontFace.h
+	src/FontFaceHandleHarfBuzz.cpp
+	src/FontFaceHandleHarfBuzz.h
+	src/FontFaceLayer.cpp
+	src/FontFaceLayer.h
+	src/FontFamily.cpp
+	src/FontFamily.h
+	src/FontGlyph.h
+	src/FontProvider.cpp
+	src/FontProvider.h
+	src/FreeTypeInterface.cpp
+	src/FreeTypeInterface.h
+	src/LanguageData.h
+	src/main.cpp
+)
+
+set_common_target_options(${TARGET_NAME})
+
+target_link_libraries(${TARGET_NAME} PRIVATE rmlui_shell Freetype::Freetype harfbuzz::harfbuzz)
+
+# Use private Core headers as a workaround for now, until we merge the HarfBuzz font engine into Core.
+target_include_directories(${TARGET_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/Source/Core)
+# Remove this check once the HarfBuzz font engine has been merged into Core.
+if(WIN32 AND BUILD_SHARED_LIBS)
+	message(FATAL_ERROR "The HarfBuzz sample cannot be built when using shared libraries on Windows. Please disable either BUILD_SHARED_LIBS or RMLUI_HARFBUZZ_SAMPLE.")
+endif()
+
+install_sample_target(${TARGET_NAME})

+ 0 - 0
Samples/basic/harfbuzzshaping/data/Cairo-Regular.ttf → Samples/basic/harfbuzz/data/Cairo-Regular.ttf


+ 0 - 0
Samples/basic/harfbuzzshaping/data/LICENSE.txt → Samples/basic/harfbuzz/data/LICENSE.txt


+ 0 - 0
Samples/basic/harfbuzzshaping/data/Poppins-Regular.ttf → Samples/basic/harfbuzz/data/Poppins-Regular.ttf


+ 0 - 0
Samples/basic/harfbuzzshaping/data/harfbuzzshaping.rml → Samples/basic/harfbuzz/data/harfbuzz.rml


+ 0 - 0
Samples/basic/harfbuzzshaping/src/FontEngineInterfaceHarfBuzz.cpp → Samples/basic/harfbuzz/src/FontEngineInterfaceHarfBuzz.cpp


+ 0 - 0
Samples/basic/harfbuzzshaping/src/FontEngineInterfaceHarfBuzz.h → Samples/basic/harfbuzz/src/FontEngineInterfaceHarfBuzz.h


+ 0 - 0
Samples/basic/harfbuzzshaping/src/FontFace.cpp → Samples/basic/harfbuzz/src/FontFace.cpp


+ 0 - 0
Samples/basic/harfbuzzshaping/src/FontFace.h → Samples/basic/harfbuzz/src/FontFace.h


+ 4 - 2
Samples/basic/harfbuzzshaping/src/FontFaceHandleHarfBuzz.cpp → Samples/basic/harfbuzz/src/FontFaceHandleHarfBuzz.cpp

@@ -531,10 +531,12 @@ void FontFaceHandleHarfBuzz::ConfigureTextShapingBuffer(hb_buffer_t* shaping_buf
 
 
 	// Set buffer flags for additional text-shaping configuration.
 	// Set buffer flags for additional text-shaping configuration.
 	int buffer_flags = HB_BUFFER_FLAG_DEFAULT | HB_BUFFER_FLAG_BOT | HB_BUFFER_FLAG_EOT;
 	int buffer_flags = HB_BUFFER_FLAG_DEFAULT | HB_BUFFER_FLAG_BOT | HB_BUFFER_FLAG_EOT;
+
+#if HB_VERSION_ATLEAST(5, 1, 0)
 	if (script == HB_SCRIPT_ARABIC)
 	if (script == HB_SCRIPT_ARABIC)
 		buffer_flags |= HB_BUFFER_FLAG_PRODUCE_SAFE_TO_INSERT_TATWEEL;
 		buffer_flags |= HB_BUFFER_FLAG_PRODUCE_SAFE_TO_INSERT_TATWEEL;
-
-#ifdef RMLUI_DEBUG
+#endif
+#if defined(RMLUI_DEBUG) && HB_VERSION_ATLEAST(3, 4, 0)
 	buffer_flags |= HB_BUFFER_FLAG_VERIFY;
 	buffer_flags |= HB_BUFFER_FLAG_VERIFY;
 #endif
 #endif
 
 

+ 0 - 0
Samples/basic/harfbuzzshaping/src/FontFaceHandleHarfBuzz.h → Samples/basic/harfbuzz/src/FontFaceHandleHarfBuzz.h


+ 0 - 0
Samples/basic/harfbuzzshaping/src/FontFaceLayer.cpp → Samples/basic/harfbuzz/src/FontFaceLayer.cpp


+ 0 - 0
Samples/basic/harfbuzzshaping/src/FontFaceLayer.h → Samples/basic/harfbuzz/src/FontFaceLayer.h


+ 0 - 0
Samples/basic/harfbuzzshaping/src/FontFamily.cpp → Samples/basic/harfbuzz/src/FontFamily.cpp


+ 0 - 0
Samples/basic/harfbuzzshaping/src/FontFamily.h → Samples/basic/harfbuzz/src/FontFamily.h


+ 0 - 0
Samples/basic/harfbuzzshaping/src/FontGlyph.h → Samples/basic/harfbuzz/src/FontGlyph.h


+ 0 - 0
Samples/basic/harfbuzzshaping/src/FontProvider.cpp → Samples/basic/harfbuzz/src/FontProvider.cpp


+ 0 - 0
Samples/basic/harfbuzzshaping/src/FontProvider.h → Samples/basic/harfbuzz/src/FontProvider.h


+ 0 - 0
Samples/basic/harfbuzzshaping/src/FreeTypeInterface.cpp → Samples/basic/harfbuzz/src/FreeTypeInterface.cpp


+ 0 - 0
Samples/basic/harfbuzzshaping/src/FreeTypeInterface.h → Samples/basic/harfbuzz/src/FreeTypeInterface.h


+ 0 - 0
Samples/basic/harfbuzzshaping/src/LanguageData.h → Samples/basic/harfbuzz/src/LanguageData.h


+ 5 - 5
Samples/basic/harfbuzzshaping/src/main.cpp → Samples/basic/harfbuzz/src/main.cpp

@@ -37,7 +37,7 @@
 */
 */
 
 
 // Toggle this variable to enable/disable text shaping.
 // Toggle this variable to enable/disable text shaping.
-constexpr bool EnableTextShaping = false;
+constexpr bool EnableTextShaping = true;
 
 
 class HarfBuzzEventListener : public Rml::EventListener {
 class HarfBuzzEventListener : public Rml::EventListener {
 public:
 public:
@@ -134,8 +134,8 @@ int main(int /*argc*/, char** /*argv*/)
 	// Load required fonts.
 	// Load required fonts.
 	Rml::String font_paths[3] = {
 	Rml::String font_paths[3] = {
 		"assets/LatoLatin-Regular.ttf",
 		"assets/LatoLatin-Regular.ttf",
-		"basic/harfbuzzshaping/data/Cairo-Regular.ttf",
-		"basic/harfbuzzshaping/data/Poppins-Regular.ttf",
+		"basic/harfbuzz/data/Cairo-Regular.ttf",
+		"basic/harfbuzz/data/Poppins-Regular.ttf",
 	};
 	};
 	for (const Rml::String& font_path : font_paths)
 	for (const Rml::String& font_path : font_paths)
 		if (!Rml::LoadFontFace(font_path))
 		if (!Rml::LoadFontFace(font_path))
@@ -147,7 +147,7 @@ int main(int /*argc*/, char** /*argv*/)
 		}
 		}
 
 
 	// Load and show the demo document.
 	// Load and show the demo document.
-	if (Rml::ElementDocument* document = context->LoadDocument("basic/harfbuzzshaping/data/harfbuzzshaping.rml"))
+	if (Rml::ElementDocument* document = context->LoadDocument("basic/harfbuzz/data/harfbuzz.rml"))
 	{
 	{
 		if (auto el = document->GetElementById("title"))
 		if (auto el = document->GetElementById("title"))
 			el->SetInnerRML("HarfBuzz Text Shaping");
 			el->SetInnerRML("HarfBuzz Text Shaping");
@@ -155,7 +155,7 @@ int main(int /*argc*/, char** /*argv*/)
 		document->Show();
 		document->Show();
 
 
 		// Create event handlers.
 		// Create event handlers.
-		for (const Rml::String& button_id : {"set-english", "set-arabic", "set-hindi"})
+		for (const Rml::String button_id : {"set-english", "set-arabic", "set-hindi"})
 			document->GetElementById(button_id)->AddEventListener(Rml::EventId::Click, new HarfBuzzEventListener(button_id, document));
 			document->GetElementById(button_id)->AddEventListener(Rml::EventId::Click, new HarfBuzzEventListener(button_id, document));
 	}
 	}
 
 

+ 12 - 0
Samples/basic/loaddocument/CMakeLists.txt

@@ -0,0 +1,12 @@
+set(SAMPLE_NAME "loaddocument")
+set(TARGET_NAME "${RMLUI_SAMPLE_PREFIX}${SAMPLE_NAME}")
+
+add_executable(${TARGET_NAME} WIN32
+	src/main.cpp
+)
+
+set_common_target_options(${TARGET_NAME})
+
+target_link_libraries(${TARGET_NAME} PRIVATE rmlui_shell)
+
+install_sample_target(${TARGET_NAME})

+ 12 - 0
Samples/basic/lottie/CMakeLists.txt

@@ -0,0 +1,12 @@
+set(SAMPLE_NAME "lottie")
+set(TARGET_NAME "${RMLUI_SAMPLE_PREFIX}${SAMPLE_NAME}")
+
+add_executable(${TARGET_NAME} WIN32
+	src/main.cpp
+)
+
+set_common_target_options(${TARGET_NAME})
+
+target_link_libraries(${TARGET_NAME} PRIVATE rmlui_shell)
+
+install_sample_target(${TARGET_NAME})

+ 12 - 0
Samples/basic/svg/CMakeLists.txt

@@ -0,0 +1,12 @@
+set(SAMPLE_NAME "svg")
+set(TARGET_NAME "${RMLUI_SAMPLE_PREFIX}${SAMPLE_NAME}")
+
+add_executable(${TARGET_NAME} WIN32
+	src/main.cpp
+)
+
+set_common_target_options(${TARGET_NAME})
+
+target_link_libraries(${TARGET_NAME} PRIVATE rmlui_shell)
+
+install_sample_target(${TARGET_NAME})

+ 12 - 0
Samples/basic/transform/CMakeLists.txt

@@ -0,0 +1,12 @@
+set(SAMPLE_NAME "transform")
+set(TARGET_NAME "${RMLUI_SAMPLE_PREFIX}${SAMPLE_NAME}")
+
+add_executable(${TARGET_NAME} WIN32
+	src/main.cpp
+)
+
+set_common_target_options(${TARGET_NAME})
+
+target_link_libraries(${TARGET_NAME} PRIVATE rmlui_shell)
+
+install_sample_target(${TARGET_NAME})

+ 14 - 0
Samples/basic/treeview/CMakeLists.txt

@@ -0,0 +1,14 @@
+set(SAMPLE_NAME "treeview")
+set(TARGET_NAME "${RMLUI_SAMPLE_PREFIX}${SAMPLE_NAME}")
+
+add_executable(${TARGET_NAME} WIN32
+	src/FileBrowser.cpp
+	src/FileBrowser.h
+	src/main.cpp
+)
+
+set_common_target_options(${TARGET_NAME})
+
+target_link_libraries(${TARGET_NAME} PRIVATE rmlui_shell)
+
+install_sample_target(${TARGET_NAME})

+ 48 - 0
Samples/invaders/CMakeLists.txt

@@ -0,0 +1,48 @@
+set(SAMPLE_NAME "invaders")
+set(TARGET_NAME "${RMLUI_SAMPLE_PREFIX}${SAMPLE_NAME}")
+
+add_executable(${TARGET_NAME} WIN32
+	src/DecoratorDefender.cpp
+	src/DecoratorDefender.h
+	src/DecoratorStarfield.cpp
+	src/DecoratorStarfield.h
+	src/Defender.cpp
+	src/Defender.h
+	src/ElementGame.cpp
+	src/ElementGame.h
+	src/EventHandler.cpp
+	src/EventHandler.h
+	src/EventHandlerHighScore.cpp
+	src/EventHandlerHighScore.h
+	src/EventHandlerOptions.cpp
+	src/EventHandlerOptions.h
+	src/EventHandlerStartGame.cpp
+	src/EventHandlerStartGame.h
+	src/EventListener.cpp
+	src/EventListener.h
+	src/EventListenerInstancer.cpp
+	src/EventListenerInstancer.h
+	src/EventManager.cpp
+	src/EventManager.h
+	src/Game.cpp
+	src/Game.h
+	src/GameDetails.cpp
+	src/GameDetails.h
+	src/HighScores.cpp
+	src/HighScores.h
+	src/Invader.cpp
+	src/Invader.h
+	src/main.cpp
+	src/Mothership.cpp
+	src/Mothership.h
+	src/Shield.cpp
+	src/Shield.h
+	src/Sprite.cpp
+	src/Sprite.h
+)
+
+set_common_target_options(${TARGET_NAME})
+
+target_link_libraries(${TARGET_NAME} PRIVATE rmlui_shell)
+
+install_sample_target(${TARGET_NAME})

+ 42 - 0
Samples/luainvaders/CMakeLists.txt

@@ -0,0 +1,42 @@
+set(SAMPLE_NAME "luainvaders")
+set(TARGET_NAME "${RMLUI_SAMPLE_PREFIX}${SAMPLE_NAME}")
+
+add_executable(${TARGET_NAME} WIN32
+	src/DecoratorDefender.cpp
+	src/DecoratorDefender.h
+	src/DecoratorStarfield.cpp
+	src/DecoratorStarfield.h
+	src/Defender.cpp
+	src/Defender.h
+	src/ElementGame.cpp
+	src/ElementGame.h
+	src/ElementGameInstancer.cpp
+	src/ElementGameInstancer.h
+	src/Game.cpp
+	src/Game.h
+	src/GameDetails.cpp
+	src/GameDetails.h
+	src/HighScores.cpp
+	src/HighScores.h
+	src/Invader.cpp
+	src/Invader.h
+	src/LuaInterface.cpp
+	src/LuaInterface.h
+	src/main.cpp
+	src/Mothership.cpp
+	src/Mothership.h
+	src/Shield.cpp
+	src/Shield.h
+	src/Sprite.cpp
+	src/Sprite.h
+)
+
+set_common_target_options(${TARGET_NAME})
+
+target_link_libraries(${TARGET_NAME} PRIVATE
+	rmlui_shell
+	rmlui_lua
+	RmlUi::External::Lua
+)
+
+install_sample_target(${TARGET_NAME})

+ 1 - 1
Samples/readme.md

@@ -19,7 +19,7 @@ This directory contains basic applications that demonstrate initialisation, usag
 -  `databinding` setting up and using data bindings
 -  `databinding` setting up and using data bindings
 -  `demo` demonstrates a variety of features in RmlUi and includes a sandbox for playing with RML/RCSS
 -  `demo` demonstrates a variety of features in RmlUi and includes a sandbox for playing with RML/RCSS
 -  `drag` dragging elements between containers
 -  `drag` dragging elements between containers
--  `harfbuzzshaping` advanced text shaping, only enabled when [HarfBuzz](https://harfbuzz.github.io/) is enabled 
+-  `harfbuzz` advanced text shaping, only enabled when [HarfBuzz](https://harfbuzz.github.io/) is enabled 
 -  `loaddocument` loading your first document
 -  `loaddocument` loading your first document
 -  `lottie` playing Lottie animations, only enabled with the [Lottie plugin](https://mikke89.github.io/RmlUiDoc/pages/cpp_manual/lottie.html)
 -  `lottie` playing Lottie animations, only enabled with the [Lottie plugin](https://mikke89.github.io/RmlUiDoc/pages/cpp_manual/lottie.html)
 -  `svg` render SVG images, only enabled with the [SVG plugin](https://mikke89.github.io/RmlUiDoc/pages/cpp_manual/svg.html)
 -  `svg` render SVG images, only enabled with the [SVG plugin](https://mikke89.github.io/RmlUiDoc/pages/cpp_manual/svg.html)

+ 29 - 0
Samples/shell/CMakeLists.txt

@@ -0,0 +1,29 @@
+#[[
+	Note: rmlui_shell is NOT a sample. It's a utility static library with code common to the RmlUi samples.
+]]
+
+add_library(rmlui_shell STATIC
+	src/PlatformExtensions.cpp
+	src/RendererExtensions.cpp
+	src/Shell.cpp
+	src/ShellFileInterface.cpp
+
+	include/PlatformExtensions.h
+	include/RendererExtensions.h
+	include/Shell.h
+	include/ShellFileInterface.h
+)
+
+set_common_target_options(rmlui_shell)
+
+target_link_libraries(rmlui_shell PRIVATE rmlui_backend_${RMLUI_BACKEND})
+
+target_include_directories(rmlui_shell PUBLIC "include" "${PROJECT_SOURCE_DIR}/Backends")
+
+if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
+	target_link_libraries(rmlui_shell PRIVATE Windows::Shell::LightweightUtility)
+elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+	target_link_libraries(rmlui_shell PRIVATE macOS::Cocoa)
+endif()
+
+target_link_libraries(rmlui_shell PUBLIC rmlui_core rmlui_debugger)

+ 21 - 6
Samples/shell/src/PlatformExtensions.cpp

@@ -55,8 +55,15 @@
 Rml::String PlatformExtensions::FindSamplesRoot()
 Rml::String PlatformExtensions::FindSamplesRoot()
 {
 {
 #ifdef RMLUI_PLATFORM_WIN32
 #ifdef RMLUI_PLATFORM_WIN32
-
-	const char* candidate_paths[] = {"", "..\\Samples\\", "..\\..\\Samples\\", "..\\..\\..\\Samples\\", "..\\..\\..\\..\\Samples\\"};
+	// Test various relative paths to the "Samples" directory, based on common build and install locations.
+	const char* candidate_paths[] = {
+		"",
+		"..\\Samples\\",
+		"..\\share\\Samples\\",
+		"..\\..\\Samples\\",
+		"..\\..\\..\\Samples\\",
+		"..\\..\\..\\..\\Samples\\",
+	};
 
 
 	// Fetch the path of the executable, test the candidate paths appended to that.
 	// Fetch the path of the executable, test the candidate paths appended to that.
 	char executable_file_name[MAX_PATH];
 	char executable_file_name[MAX_PATH];
@@ -85,6 +92,8 @@ Rml::String PlatformExtensions::FindSamplesRoot()
 		}
 		}
 	}
 	}
 
 
+	Rml::Log::Message(Rml::Log::LT_ERROR, "Failed to find the path to the samples root");
+
 	return Rml::String();
 	return Rml::String();
 
 
 #elif defined RMLUI_PLATFORM_MACOSX
 #elif defined RMLUI_PLATFORM_MACOSX
@@ -133,10 +142,16 @@ Rml::String PlatformExtensions::FindSamplesRoot()
 	// We assume we have found the correct path if we can find the lookup file from it.
 	// We assume we have found the correct path if we can find the lookup file from it.
 	const char* lookup_file = "assets/rml.rcss";
 	const char* lookup_file = "assets/rml.rcss";
 
 
-	// For "../Samples/" to be valid we must be in the Build directory.
-	// If "../" is valid we are probably in the installation directory.
-	// Some build setups may nest the executables deeper in a build directory, try them last.
-	const char* candidate_paths[] = {"", "../", "../Samples/", "../../Samples/", "../../../Samples/", "../../../../Samples/"};
+	// Test various relative paths to the "Samples" directory, based on common build and install locations.
+	const char* candidate_paths[] = {
+		"",
+		"../",
+		"../Samples/",
+		"../share/Samples/",
+		"../../Samples/",
+		"../../../Samples/",
+		"../../../../Samples/",
+	};
 
 
 	auto isRegularFile = [](const Rml::String& path) -> bool {
 	auto isRegularFile = [](const Rml::String& path) -> bool {
 		struct stat sb;
 		struct stat sb;

+ 4 - 0
Samples/tutorial/CMakeLists.txt

@@ -0,0 +1,4 @@
+set(RMLUI_TUTORIAL_PREFIX "rmlui_tutorial_")
+
+add_subdirectory("drag")
+add_subdirectory("template")

+ 14 - 0
Samples/tutorial/drag/CMakeLists.txt

@@ -0,0 +1,14 @@
+set(TUTORIAL_NAME "drag")
+set(TARGET_NAME "${RMLUI_TUTORIAL_PREFIX}${TUTORIAL_NAME}")
+
+add_executable(${TARGET_NAME} WIN32
+	src/Inventory.cpp
+	src/Inventory.h
+	src/main.cpp
+)
+
+set_common_target_options(${TARGET_NAME})
+
+target_link_libraries(${TARGET_NAME} PRIVATE rmlui_shell)
+
+install_sample_target(${TARGET_NAME})

+ 12 - 0
Samples/tutorial/template/CMakeLists.txt

@@ -0,0 +1,12 @@
+set(TUTORIAL_NAME "template")
+set(TARGET_NAME "${RMLUI_TUTORIAL_PREFIX}${TUTORIAL_NAME}")
+
+add_executable(${TARGET_NAME} WIN32
+	src/main.cpp
+)
+
+set_common_target_options(${TARGET_NAME})
+
+target_link_libraries(${TARGET_NAME} PRIVATE rmlui_shell)
+
+install_sample_target(${TARGET_NAME})

+ 14 - 0
Source/CMakeLists.txt

@@ -0,0 +1,14 @@
+add_subdirectory("Core")
+
+if(RMLUI_LOTTIE_PLUGIN)
+	add_subdirectory("Lottie")
+endif()
+if(RMLUI_SVG_PLUGIN)
+	add_subdirectory("SVG")
+endif()
+
+add_subdirectory("Debugger")
+
+if(RMLUI_LUA_BINDINGS)
+	add_subdirectory("Lua")
+endif()

+ 467 - 0
Source/Core/CMakeLists.txt

@@ -0,0 +1,467 @@
+# Declare RmlUi core library
+# Not explicitly setting library type so that it can be chosen by consumer using BUILD_SHARED_LIBS. Header files are not
+# necessary, but are included to improve navigation and code completion on IDEs and language servers.
+add_library(rmlui_core
+	BaseXMLParser.cpp
+	Box.cpp
+	CallbackTexture.cpp
+	Clock.cpp
+	Clock.h
+	CompiledFilterShader.cpp
+	ComputedValues.cpp
+	ComputeProperty.cpp
+	ComputeProperty.h
+	Context.cpp
+	ContextInstancer.cpp
+	ContextInstancerDefault.cpp
+	ContextInstancerDefault.h
+	ConvolutionFilter.cpp
+	Core.cpp
+	DataController.cpp
+	DataController.h
+	DataControllerDefault.cpp
+	DataControllerDefault.h
+	DataExpression.cpp
+	DataExpression.h
+	DataModel.cpp
+	DataModel.h
+	DataModelHandle.cpp
+	DataTypeRegister.cpp
+	DataVariable.cpp
+	DataView.cpp
+	DataView.h
+	DataViewDefault.cpp
+	DataViewDefault.h
+	Decorator.cpp
+	DecoratorGradient.cpp
+	DecoratorGradient.h
+	DecoratorNinePatch.cpp
+	DecoratorNinePatch.h
+	DecoratorShader.cpp
+	DecoratorShader.h
+	DecoratorTiled.cpp
+	DecoratorTiled.h
+	DecoratorTiledBox.cpp
+	DecoratorTiledBox.h
+	DecoratorTiledHorizontal.cpp
+	DecoratorTiledHorizontal.h
+	DecoratorTiledImage.cpp
+	DecoratorTiledImage.h
+	DecoratorTiledVertical.cpp
+	DecoratorTiledVertical.h
+	DocumentHeader.cpp
+	DocumentHeader.h
+	EffectSpecification.cpp
+	Element.cpp
+	ElementAnimation.cpp
+	ElementAnimation.h
+	ElementBackgroundBorder.cpp
+	ElementBackgroundBorder.h
+	ElementDefinition.cpp
+	ElementDefinition.h
+	ElementDocument.cpp
+	ElementEffects.cpp
+	ElementEffects.h
+	ElementHandle.cpp
+	ElementHandle.h
+	ElementInstancer.cpp
+	ElementScroll.cpp
+	ElementStyle.cpp
+	ElementStyle.h
+	ElementText.cpp
+	ElementUtilities.cpp
+	Event.cpp
+	EventDispatcher.cpp
+	EventDispatcher.h
+	EventInstancer.cpp
+	EventInstancerDefault.cpp
+	EventInstancerDefault.h
+	EventListenerInstancer.cpp
+	EventSpecification.cpp
+	EventSpecification.h
+	Factory.cpp
+	FileInterface.cpp
+	FileInterfaceDefault.cpp
+	FileInterfaceDefault.h
+	Filter.cpp
+	FilterBasic.cpp
+	FilterBasic.h
+	FilterBlur.cpp
+	FilterBlur.h
+	FilterDropShadow.cpp
+	FilterDropShadow.h
+	FontEffect.cpp
+	FontEffectBlur.cpp
+	FontEffectBlur.h
+	FontEffectGlow.cpp
+	FontEffectGlow.h
+	FontEffectInstancer.cpp
+	FontEffectOutline.cpp
+	FontEffectOutline.h
+	FontEffectShadow.cpp
+	FontEffectShadow.h
+	FontEngineInterface.cpp
+	Geometry.cpp
+	GeometryBackgroundBorder.cpp
+	GeometryBackgroundBorder.h
+	GeometryBoxShadow.cpp
+	GeometryBoxShadow.h
+	IdNameMap.h
+	Log.cpp
+	LogDefault.cpp
+	LogDefault.h
+	Math.cpp
+	Memory.cpp
+	Memory.h
+	MeshUtilities.cpp
+	ObserverPtr.cpp
+	Plugin.cpp
+	PluginRegistry.cpp
+	PluginRegistry.h
+	Pool.h
+	precompiled.h
+	Profiling.cpp
+	PropertiesIterator.h
+	PropertiesIteratorView.cpp
+	Property.cpp
+	PropertyDefinition.cpp
+	PropertyDictionary.cpp
+	PropertyParserAnimation.cpp
+	PropertyParserAnimation.h
+	PropertyParserBoxShadow.cpp
+	PropertyParserBoxShadow.h
+	PropertyParserColorStopList.cpp
+	PropertyParserColorStopList.h
+	PropertyParserColour.cpp
+	PropertyParserColour.h
+	PropertyParserDecorator.cpp
+	PropertyParserDecorator.h
+	PropertyParserFilter.cpp
+	PropertyParserFilter.h
+	PropertyParserFontEffect.cpp
+	PropertyParserFontEffect.h
+	PropertyParserKeyword.cpp
+	PropertyParserKeyword.h
+	PropertyParserNumber.cpp
+	PropertyParserNumber.h
+	PropertyParserRatio.cpp
+	PropertyParserRatio.h
+	PropertyParserString.cpp
+	PropertyParserString.h
+	PropertyParserTransform.cpp
+	PropertyParserTransform.h
+	PropertyShorthandDefinition.h
+	PropertySpecification.cpp
+	RenderInterface.cpp
+	RenderInterfaceCompatibility.cpp
+	RenderManager.cpp
+	RenderManagerAccess.cpp
+	RenderManagerAccess.h
+	ScrollController.cpp
+	ScrollController.h
+	Spritesheet.cpp
+	Stream.cpp
+	StreamFile.cpp
+	StreamFile.h
+	StreamMemory.cpp
+	StringUtilities.cpp
+	StyleSheet.cpp
+	StyleSheetContainer.cpp
+	StyleSheetFactory.cpp
+	StyleSheetFactory.h
+	StyleSheetNode.cpp
+	StyleSheetNode.h
+	StyleSheetParser.cpp
+	StyleSheetParser.h
+	StyleSheetSelector.cpp
+	StyleSheetSelector.h
+	StyleSheetSpecification.cpp
+	SystemInterface.cpp
+	Template.cpp
+	Template.h
+	TemplateCache.cpp
+	TemplateCache.h
+	Texture.cpp
+	TextureDatabase.cpp
+	TextureDatabase.h
+	TextureLayout.cpp
+	TextureLayout.h
+	TextureLayoutRectangle.cpp
+	TextureLayoutRectangle.h
+	TextureLayoutRow.cpp
+	TextureLayoutRow.h
+	TextureLayoutTexture.cpp
+	TextureLayoutTexture.h
+	Transform.cpp
+	TransformPrimitive.cpp
+	TransformState.cpp
+	TransformState.h
+	TransformUtilities.cpp
+	TransformUtilities.h
+	Tween.cpp
+	TypeConverter.cpp
+	URL.cpp
+	Variant.cpp
+	WidgetScroll.cpp
+	WidgetScroll.h
+	XMLNodeHandler.cpp
+	XMLNodeHandlerBody.cpp
+	XMLNodeHandlerBody.h
+	XMLNodeHandlerDefault.cpp
+	XMLNodeHandlerDefault.h
+	XMLNodeHandlerHead.cpp
+	XMLNodeHandlerHead.h
+	XMLNodeHandlerTemplate.cpp
+	XMLNodeHandlerTemplate.h
+	XMLParser.cpp
+	XMLParseTools.cpp
+	XMLParseTools.h
+)
+
+# Add public headers as files in the project (it's not necessary but convenient for IDE integration)
+# Setting them as PRIVATE so that it's addition doesn't propagate, it won't affect availability since
+# the entire include directory has already been declared as public
+target_sources(rmlui_core PRIVATE
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Config/Config.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/BaseXMLParser.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Box.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/CallbackTexture.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Colour.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Colour.inl"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/CompiledFilterShader.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/ComputedValues.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Containers/itlib/flat_map.hpp"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Containers/itlib/flat_set.hpp"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Containers/LICENSE.txt"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Containers/robin_hood.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Context.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/ContextInstancer.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/ConvolutionFilter.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Core.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/DataModelHandle.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/DataStructHandle.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/DataTypeRegister.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/DataTypes.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/DataVariable.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Debug.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/DecorationTypes.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Decorator.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Dictionary.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/EffectSpecification.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Element.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Element.inl"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/ElementDocument.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/ElementInstancer.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/ElementScroll.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Elements/ElementForm.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Elements/ElementFormControl.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Elements/ElementFormControlInput.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Elements/ElementFormControlSelect.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Elements/ElementFormControlTextArea.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Elements/ElementProgress.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Elements/ElementTabSet.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/ElementText.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/ElementUtilities.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Event.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/EventInstancer.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/EventListener.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/EventListenerInstancer.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Factory.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/FileInterface.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Filter.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/FontEffect.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/FontEffectInstancer.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/FontEngineInterface.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/FontGlyph.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/FontMetrics.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Geometry.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Header.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/ID.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Input.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Log.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Math.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Matrix4.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Matrix4.inl"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Mesh.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/MeshUtilities.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/NumericValue.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/ObserverPtr.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Platform.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Plugin.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Profiling.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/PropertiesIteratorView.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Property.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/PropertyDefinition.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/PropertyDictionary.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/PropertyIdSet.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/PropertyParser.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/PropertySpecification.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Rectangle.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/RenderInterface.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/RenderInterfaceCompatibility.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/RenderManager.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/ScriptInterface.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/ScrollTypes.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Span.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Spritesheet.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/StableVector.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Stream.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/StreamMemory.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/StringUtilities.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/StyleSheet.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/StyleSheetContainer.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/StyleSheetSpecification.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/StyleSheetTypes.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/StyleTypes.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/SystemInterface.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/TextShapingContext.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Texture.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Traits.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Transform.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/TransformPrimitive.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Tween.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/TypeConverter.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/TypeConverter.inl"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Types.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/UniqueRenderResource.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Unit.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/URL.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Utilities.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Variant.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Variant.inl"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Vector2.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Vector2.inl"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Vector3.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Vector3.inl"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Vector4.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Vector4.inl"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Vertex.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/XMLNodeHandler.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/XMLParser.h"
+)
+
+set_common_target_options(rmlui_core)
+
+target_include_directories(rmlui_core PRIVATE "${PROJECT_SOURCE_DIR}/Include")
+target_include_directories(rmlui_core INTERFACE
+	"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/Include>"
+	"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
+)
+
+add_library(RmlUi::Core ALIAS rmlui_core)
+
+set_target_properties(rmlui_core PROPERTIES
+	# Add export name so that it can be exported with a namespaced name instead
+	# of using the name we actually used to declare the target
+	EXPORT_NAME "Core"
+
+	# Change output name of the final library file
+	OUTPUT_NAME "rmlui"
+)
+
+generate_rmlui_version_string()
+target_compile_definitions(rmlui_core PRIVATE "RMLUI_VERSION=\"${RMLUI_VERSION_SHORT}\"")
+
+add_subdirectory("Elements")
+add_subdirectory("Layout")
+
+# Set up definitions to export functions and classes as appropriate
+get_target_property(rmlui_core_TYPE rmlui_core "TYPE")
+if(rmlui_core_TYPE STREQUAL "STATIC_LIBRARY")
+	# If RmlUi is being compiled as a static library, notify code to disable usage of __dllspec()
+	# Since public headers also detect it, it needs to be a public definition
+	target_compile_definitions(rmlui_core PUBLIC "RMLUI_STATIC_LIB")
+elseif(rmlui_core_TYPE STREQUAL "SHARED_LIBRARY")
+	# If RmlUi is being compiled as a shared library, notify code to export functions using __dllspec()
+	# For applications consuming the library, the headers will automatically use dllimport
+	# Platform and compiler handling is already done by code via pre-processor macros
+	target_compile_definitions(rmlui_core PRIVATE "RMLUI_CORE_EXPORTS")
+endif()
+unset(rmlui_core_TYPE)
+
+if(RMLUI_FONT_ENGINE STREQUAL "freetype")
+	# Include the source files for the default font engine.
+	add_subdirectory("FontEngineDefault")
+
+	# RMLUI_CMAKE_MINIMUM_VERSION_RAISE_NOTICE:
+	# From CMake 3.13 the next line can be moved into `FontEngineDefault/CMakeLists.txt`, see CMP0079.
+	target_link_libraries(rmlui_core PRIVATE Freetype::Freetype)
+endif()
+
+if(RMLUI_LOTTIE_PLUGIN)
+	# RMLUI_CMAKE_MINIMUM_VERSION_RAISE_NOTICE:
+	# From CMake 3.13 we could move this to `Lottie/CMakeLists.txt`, see CMP0079.
+	target_link_libraries(rmlui_core PRIVATE rlottie::rlottie)
+endif()
+
+if(RMLUI_SVG_PLUGIN)
+	# RMLUI_CMAKE_MINIMUM_VERSION_RAISE_NOTICE:
+	# From CMake 3.13 we could move this to `Lottie/CMakeLists.txt`, see CMP0079.
+	target_link_libraries(rmlui_core PRIVATE lunasvg::lunasvg)
+endif()
+
+if(RMLUI_TRACY_PROFILING)
+	if(CMAKE_CONFIGURATION_TYPES AND RMLUI_TRACY_CONFIGURATION)
+		target_link_libraries(rmlui_core PUBLIC "$<$<CONFIG:Tracy>:Tracy::TracyClient>")
+		target_compile_definitions(rmlui_core PUBLIC "$<$<CONFIG:Tracy>:RMLUI_TRACY_PROFILING>")
+		if(RMLUI_TRACY_MEMORY_PROFILING)
+			target_compile_definitions(rmlui_core PRIVATE "$<$<CONFIG:Tracy>:RMLUI_TRACY_MEMORY_PROFILING>")
+		endif()
+		message(STATUS "Tracy profiling enabled in configuration `Tracy`.")
+	else()
+		target_link_libraries(rmlui_core PUBLIC Tracy::TracyClient)
+		target_compile_definitions(rmlui_core PUBLIC "RMLUI_TRACY_PROFILING")
+		if(RMLUI_TRACY_MEMORY_PROFILING)
+			target_compile_definitions(rmlui_core PRIVATE "RMLUI_TRACY_MEMORY_PROFILING")
+		endif()
+		message(STATUS "Tracy profiling enabled.")
+	endif()
+endif()
+
+if(NOT RMLUI_THIRDPARTY_CONTAINERS)
+	target_compile_definitions(rmlui_core PUBLIC "RMLUI_NO_THIRDPARTY_CONTAINERS")
+	message(STATUS "Disabling third-party containers for RmlUi.")
+endif()
+
+if(RMLUI_CUSTOM_RTTI)
+	target_compile_definitions(rmlui_core PUBLIC "RMLUI_CUSTOM_RTTI")
+	message(STATUS "Enabling custom RTTI for RmlUi.")
+endif()
+
+if(RMLUI_MATRIX_ROW_MAJOR)
+	target_compile_definitions(rmlui_core PUBLIC "RMLUI_MATRIX_ROW_MAJOR")
+	message(STATUS "Configuring RmlUi to use row-major matrix types.")
+endif()
+
+# RMLUI_CMAKE_MINIMUM_VERSION_RAISE_NOTICE:
+# From CMake 3.16 we can skip the version check.
+if(RMLUI_PRECOMPILED_HEADERS AND CMAKE_VERSION VERSION_GREATER_EQUAL "3.16")
+	target_precompile_headers(rmlui_core PRIVATE "${PROJECT_SOURCE_DIR}/Source/Core/precompiled.h")
+elseif(RMLUI_PRECOMPILED_HEADERS)
+	message(STATUS "Could not enable precompiled headers, requires CMake version 3.16 or greater.")
+endif()
+
+if(RMLUI_CUSTOM_CONFIGURATION AND RMLUI_CUSTOM_CONFIGURATION_FILE)
+	target_compile_definitions(rmlui_core PUBLIC "RMLUI_CUSTOM_CONFIGURATION_FILE=\"${RMLUI_CUSTOM_CONFIGURATION_FILE}\"")
+	message(STATUS "Including ${RMLUI_CUSTOM_CONFIGURATION_FILE} instead of <RmlUi/Config/Config.h>")
+endif()
+if(RMLUI_CUSTOM_CONFIGURATION AND RMLUI_CUSTOM_INCLUDE_DIRS)
+	target_include_directories(rmlui_core PUBLIC ${RMLUI_CUSTOM_INCLUDE_DIRS})
+endif()
+if(RMLUI_CUSTOM_CONFIGURATION AND RMLUI_CUSTOM_LINK_LIBRARIES)
+	target_link_libraries(rmlui_core PUBLIC ${RMLUI_CUSTOM_LINK_LIBRARIES})
+endif()
+
+# RMLUI_CMAKE_MINIMUM_VERSION_RAISE_NOTICE:
+# We use default paths provided from GNUInstallDirs. From CMake 3.14 these paths (CMAKE_INSTALL_...) will be used
+# automatically and can be removed from the following call. The same applies to many other calls to install(TARGETS...).
+# Note that GNUInstallDirs should still be included in the project root.
+install(TARGETS rmlui_core
+	EXPORT RmlUiTargets
+	${RMLUI_RUNTIME_DEPENDENCY_SET_ARG}
+	RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+	LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+	ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)
+install_target_pdb(rmlui_core)

+ 6 - 6
Source/Core/Core.cpp

@@ -47,15 +47,15 @@
 #include "TemplateCache.h"
 #include "TemplateCache.h"
 #include "TextureDatabase.h"
 #include "TextureDatabase.h"
 
 
-#ifndef RMLUI_NO_FONT_INTERFACE_DEFAULT
+#ifdef RMLUI_FONT_ENGINE_FREETYPE
 	#include "FontEngineDefault/FontEngineInterfaceDefault.h"
 	#include "FontEngineDefault/FontEngineInterfaceDefault.h"
 #endif
 #endif
 
 
-#ifdef RMLUI_ENABLE_LOTTIE_PLUGIN
+#ifdef RMLUI_LOTTIE_PLUGIN
 	#include "../Lottie/LottiePlugin.h"
 	#include "../Lottie/LottiePlugin.h"
 #endif
 #endif
 
 
-#ifdef RMLUI_ENABLE_SVG_PLUGIN
+#ifdef RMLUI_SVG_PLUGIN
 	#include "../SVG/SVGPlugin.h"
 	#include "../SVG/SVGPlugin.h"
 #endif
 #endif
 
 
@@ -115,7 +115,7 @@ bool Initialise()
 
 
 	if (!font_interface)
 	if (!font_interface)
 	{
 	{
-#ifndef RMLUI_NO_FONT_INTERFACE_DEFAULT
+#ifdef RMLUI_FONT_ENGINE_FREETYPE
 		default_font_interface = MakeUnique<FontEngineInterfaceDefault>();
 		default_font_interface = MakeUnique<FontEngineInterfaceDefault>();
 		font_interface = default_font_interface.get();
 		font_interface = default_font_interface.get();
 #else
 #else
@@ -141,10 +141,10 @@ bool Initialise()
 	Factory::Initialise();
 	Factory::Initialise();
 
 
 	// Initialise plugins integrated with Core.
 	// Initialise plugins integrated with Core.
-#ifdef RMLUI_ENABLE_LOTTIE_PLUGIN
+#ifdef RMLUI_LOTTIE_PLUGIN
 	Lottie::Initialise();
 	Lottie::Initialise();
 #endif
 #endif
-#ifdef RMLUI_ENABLE_SVG_PLUGIN
+#ifdef RMLUI_SVG_PLUGIN
 	SVG::Initialise();
 	SVG::Initialise();
 #endif
 #endif
 
 

+ 50 - 0
Source/Core/Elements/CMakeLists.txt

@@ -0,0 +1,50 @@
+# RMLUI_CMAKE_MINIMUM_VERSION_RAISE_NOTICE:
+# Using absolute paths to prevent improper interpretation of relative paths. Relative paths can be used once the minimum
+# CMake version is greater or equal than CMake 3.13
+target_sources(rmlui_core PRIVATE
+	"${CMAKE_CURRENT_SOURCE_DIR}/ElementFormControl.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/ElementFormControlInput.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/ElementFormControlSelect.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/ElementFormControlTextArea.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/ElementForm.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/ElementImage.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/ElementImage.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/ElementLabel.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/ElementLabel.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/ElementProgress.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/ElementTabSet.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/ElementTextSelection.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/ElementTextSelection.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/InputTypeButton.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/InputTypeButton.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/InputTypeCheckbox.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/InputTypeCheckbox.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/InputType.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/InputType.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/InputTypeRadio.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/InputTypeRadio.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/InputTypeRange.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/InputTypeRange.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/InputTypeSubmit.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/InputTypeSubmit.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/InputTypeText.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/InputTypeText.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/WidgetDropDown.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/WidgetDropDown.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/WidgetSlider.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/WidgetSlider.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/WidgetTextInput.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/WidgetTextInput.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/WidgetTextInputMultiLine.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/WidgetTextInputMultiLine.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/WidgetTextInputSingleLine.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/WidgetTextInputSingleLine.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/WidgetTextInputSingleLinePassword.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/WidgetTextInputSingleLinePassword.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/XMLNodeHandlerSelect.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/XMLNodeHandlerSelect.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/XMLNodeHandlerTabSet.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/XMLNodeHandlerTabSet.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/XMLNodeHandlerTextArea.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/XMLNodeHandlerTextArea.h"
+)

+ 22 - 0
Source/Core/FontEngineDefault/CMakeLists.txt

@@ -0,0 +1,22 @@
+# RMLUI_CMAKE_MINIMUM_VERSION_RAISE_NOTICE:
+# Using absolute paths to prevent improper interpretation of relative paths Relative paths can be used once the minimum
+# CMake version is greater or equal than CMake 3.13
+target_sources(rmlui_core PRIVATE
+	"${CMAKE_CURRENT_SOURCE_DIR}/FontEngineInterfaceDefault.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/FontEngineInterfaceDefault.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/FontFace.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/FontFace.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/FontFaceHandleDefault.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/FontFaceHandleDefault.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/FontFaceLayer.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/FontFaceLayer.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/FontFamily.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/FontFamily.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/FontProvider.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/FontProvider.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/FontTypes.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/FreeTypeInterface.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/FreeTypeInterface.h"
+)
+
+target_compile_definitions(rmlui_core PRIVATE "RMLUI_FONT_ENGINE_FREETYPE")

+ 40 - 0
Source/Core/Layout/CMakeLists.txt

@@ -0,0 +1,40 @@
+# RMLUI_CMAKE_MINIMUM_VERSION_RAISE_NOTICE:
+# Using absolute paths to prevent improper interpretation of relative paths Relative paths can be used once the minimum
+# CMake version is greater or equal than CMake 3.13
+target_sources(rmlui_core PRIVATE
+	"${CMAKE_CURRENT_SOURCE_DIR}/BlockContainer.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/BlockContainer.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/BlockFormattingContext.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/BlockFormattingContext.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/ContainerBox.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/ContainerBox.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/FlexFormattingContext.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/FlexFormattingContext.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/FloatedBoxSpace.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/FloatedBoxSpace.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/FormattingContext.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/FormattingContext.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/InlineBox.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/InlineBox.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/InlineContainer.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/InlineContainer.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/InlineLevelBox.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/InlineLevelBox.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/InlineTypes.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/LayoutBox.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/LayoutBox.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/LayoutDetails.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/LayoutDetails.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/LayoutEngine.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/LayoutEngine.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/LayoutPools.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/LayoutPools.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/LineBox.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/LineBox.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/ReplacedFormattingContext.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/ReplacedFormattingContext.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/TableFormattingContext.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/TableFormattingContext.h"
+	"${CMAKE_CURRENT_SOURCE_DIR}/TableFormattingDetails.cpp"
+	"${CMAKE_CURRENT_SOURCE_DIR}/TableFormattingDetails.h"
+)

+ 67 - 0
Source/Debugger/CMakeLists.txt

@@ -0,0 +1,67 @@
+add_library(rmlui_debugger
+	BeaconSource.h
+	CommonSource.h
+	Debugger.cpp
+	DebuggerPlugin.cpp
+	DebuggerPlugin.h
+	DebuggerSystemInterface.cpp
+	DebuggerSystemInterface.h
+	ElementContextHook.cpp
+	ElementContextHook.h
+	ElementInfo.cpp
+	ElementInfo.h
+	ElementLog.cpp
+	ElementLog.h
+	FontSource.h
+	Geometry.cpp
+	Geometry.h
+	InfoSource.h
+	LogSource.h
+	MenuSource.h
+)
+
+set_common_target_options(rmlui_debugger)
+
+target_include_directories(rmlui_debugger PRIVATE "${PROJECT_SOURCE_DIR}/Include")
+target_include_directories(rmlui_debugger INTERFACE
+	"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/Include>"
+	"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
+)
+
+# Add public headers as files in the project (it's not necessary but convenient for IDE integration)
+# Setting them as PRIVATE so that it's addition doesn't propagate, it won't affect availability since
+# the entire include directory has already been declared as public
+target_sources(rmlui_debugger PRIVATE
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Debugger/Debugger.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Debugger/Header.h"
+	"${PROJECT_SOURCE_DIR}/Include/RmlUi/Debugger.h"
+)
+
+target_link_libraries(rmlui_debugger PUBLIC rmlui_core)
+
+add_library(RmlUi::Debugger ALIAS rmlui_debugger)
+
+# Set up definitions to export functions and classes as appropriate
+get_target_property(rmlui_debugger_TYPE rmlui_debugger "TYPE")
+if(rmlui_debugger_TYPE STREQUAL "SHARED_LIBRARY")
+	# If RmlUi debugger is being compiled as a shared library, notify code to export functions using __dllspec()
+	# For applications consuming the library, the headers will automatically use dllimport
+	# Platform and compiler handling is already done by code via pre-processor macros
+	target_compile_definitions(rmlui_debugger PRIVATE "RMLUI_DEBUGGER_EXPORTS")
+endif()
+
+# Set additional target properties
+set_target_properties(rmlui_debugger PROPERTIES
+	# Add export name so that it can be exported with a namespaced name instead
+	# of using the name we actually used to declare the target
+	EXPORT_NAME "Debugger"
+)
+
+install(TARGETS rmlui_debugger
+	EXPORT RmlUiTargets
+	${RMLUI_RUNTIME_DEPENDENCY_SET_ARG}
+	RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+	LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+	ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)
+install_target_pdb(rmlui_debugger)

Some files were not shown because too many files changed in this diff