diff --git a/.gitmodules b/.gitmodules
index a02944f..d040fd1 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -13,3 +13,6 @@
 [submodule "lib/mm-decomp"]
 	path = lib/mm-decomp
 	url = https://github.com/zeldaret/mm
+[submodule "lib/lunasvg"]
+	path = lib/lunasvg
+	url = https://github.com/sammycage/lunasvg
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0e1936c..c3825ac 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -16,6 +16,13 @@ set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/lib/")
 
 add_subdirectory(${CMAKE_SOURCE_DIR}/lib/RT64-HLE ${CMAKE_BINARY_DIR}/rt64)
+
+# set(BUILD_SHARED_LIBS_SAVED "${BUILD_SHARED_LIBS}")
+set(BUILD_SHARED_LIBS OFF)
+SET(LUNASVG_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
+add_subdirectory(${CMAKE_SOURCE_DIR}/lib/lunasvg)
+# set(BUILD_SHARED_LIBS "${BUILD_SHARED_LIBS_SAVED}")
+SET(ENABLE_SVG_PLUGIN ON CACHE BOOL "" FORCE)
 add_subdirectory(${CMAKE_SOURCE_DIR}/lib/RmlUi)
 add_subdirectory(${CMAKE_SOURCE_DIR}/lib/nativefiledialog-extended)
 
@@ -157,6 +164,7 @@ target_link_libraries(MMRecomp PRIVATE
     RmlCore
     RmlDebugger
     nfd
+    lunasvg
 )
 
 # TODO fix the RT64 CMake script so that this doesn't need to be duplicated here
diff --git a/assets/mask.svg b/assets/mask.svg
new file mode 100644
index 0000000..d4c6bd2
--- /dev/null
+++ b/assets/mask.svg
@@ -0,0 +1,103 @@
+
+
\ No newline at end of file
diff --git a/lib/lunasvg b/lib/lunasvg
new file mode 160000
index 0000000..73cc40b
--- /dev/null
+++ b/lib/lunasvg
@@ -0,0 +1 @@
+Subproject commit 73cc40b482d0adad226ad101bff40d8ffa69ffeb
diff --git a/src/ui/ui_renderer.cpp b/src/ui/ui_renderer.cpp
index 932b61f..47a33ef 100644
--- a/src/ui/ui_renderer.cpp
+++ b/src/ui/ui_renderer.cpp
@@ -97,8 +97,10 @@ class RmlRenderInterface_RT64 : public Rml::RenderInterface {
     static constexpr uint32_t initial_upload_buffer_size = 1024 * 1024;
     static constexpr uint32_t initial_vertex_buffer_size = 512 * sizeof(Rml::Vertex);
     static constexpr uint32_t initial_index_buffer_size = 1024 * sizeof(int);
-    static constexpr RT64::RenderFormat RmlTextureFormat = RT64::RenderFormat::B8G8R8A8_UNORM;
+    static constexpr RT64::RenderFormat RmlTextureFormat = RT64::RenderFormat::R8G8B8A8_UNORM;
+    static constexpr RT64::RenderFormat RmlTextureFormatBgra = RT64::RenderFormat::B8G8R8A8_UNORM;
     static constexpr uint32_t RmlTextureFormatBytesPerPixel = RenderFormatSize(RmlTextureFormat);
+    static_assert(RenderFormatSize(RmlTextureFormatBgra) == RmlTextureFormatBytesPerPixel);
     struct UIRenderContext* render_context_;
     int scissor_x_ = 0;
     int scissor_y_ = 0;
@@ -433,7 +435,7 @@ public:
             texture_dimensions.y = size_y;
 
             texture_handle = texture_count_++;
-            create_texture(texture_handle, reinterpret_cast(file_data.data() + 18), texture_dimensions, true);
+            create_texture(texture_handle, reinterpret_cast(file_data.data() + 18), texture_dimensions, true, true);
 
             return true;
         }
@@ -442,13 +444,18 @@ public:
     }
 
     bool GenerateTexture(Rml::TextureHandle& texture_handle, const Rml::byte* source, const Rml::Vector2i& source_dimensions) override {
+        if (source_dimensions.x == 0 || source_dimensions.y == 0) {
+            texture_handle = 0;
+            return true;
+        }
+
         texture_handle = texture_count_++;
         return create_texture(texture_handle, source, source_dimensions);
     }
 
-    bool create_texture(Rml::TextureHandle texture_handle, const Rml::byte* source, const Rml::Vector2i& source_dimensions, bool flip_y = false) {
+    bool create_texture(Rml::TextureHandle texture_handle, const Rml::byte* source, const Rml::Vector2i& source_dimensions, bool flip_y = false, bool bgra = false) {
         std::unique_ptr texture =
-            render_context_->device->createTexture(RT64::RenderTextureDesc::Texture2D(source_dimensions.x, source_dimensions.y, 1, RmlTextureFormat));
+            render_context_->device->createTexture(RT64::RenderTextureDesc::Texture2D(source_dimensions.x, source_dimensions.y, 1, bgra ? RmlTextureFormatBgra : RmlTextureFormat));
 
         if (texture != nullptr) {
             uint32_t image_size_bytes = source_dimensions.x * source_dimensions.y * RmlTextureFormatBytesPerPixel;