瀏覽代碼

Merge branch 'develop' into text

# Conflicts:
#	CMake/FileList.cmake
#	Source/Core/BitmapFont/BitmapFontDefinitions.h
#	Source/Core/BitmapFont/FontFace.cpp
#	Source/Core/BitmapFont/FontFace.h
#	Source/Core/BitmapFont/FontFaceHandle.cpp
#	Source/Core/BitmapFont/FontFaceHandle.h
#	Source/Core/BitmapFont/FontFaceLayer.cpp
#	Source/Core/BitmapFont/FontFaceLayer.h
#	Source/Core/BitmapFont/FontFamily.cpp
#	Source/Core/BitmapFont/FontFamily.h
#	Source/Core/BitmapFont/FontParser.cpp
#	Source/Core/BitmapFont/FontParser.h
#	Source/Core/BitmapFont/FontProvider.cpp
#	Source/Core/BitmapFont/FontProvider.h
#	Source/Core/BitmapFont/precompiled.h
#	Source/Core/ElementStyle.cpp
#	Source/Core/ElementTextDefault.cpp
#	Source/Core/ElementUtilities.cpp
#	Source/Core/FontDatabaseDefault.cpp
#	Source/Core/FontDatabaseDefault.h
#	Source/Core/FontFace.h
#	Source/Core/FontFaceHandleDefault.cpp
#	Source/Core/FontFaceHandleDefault.h
#	Source/Core/FontFaceLayer.h
#	Source/Core/FontFamily.cpp
#	Source/Core/FontFamily.h
#	Source/Core/FontProvider.cpp
#	Source/Core/FontProvider.h
#	Source/Core/FreeType/FontFace.cpp
#	Source/Core/FreeType/FontFace.h
#	Source/Core/FreeType/FontFaceHandle.h
#	Source/Core/FreeType/FontFamily.h
#	Source/Core/FreeType/FontProvider.cpp
#	Source/Core/FreeType/FontProvider.h
#	Source/Core/TextureResource.cpp
#	Source/Debugger/Plugin.cpp
Michael Ragazzon 6 年之前
父節點
當前提交
2438824c95
共有 61 個文件被更改,包括 870 次插入379 次删除
  1. 15 1
      .travis.yml
  2. 12 8
      CMake/FileList.cmake
  3. 12 5
      CMakeLists.txt
  4. 1 3
      Include/RmlUi/Core/ComputedValues.h
  5. 6 1
      Include/RmlUi/Core/Core.h
  6. 2 2
      Include/RmlUi/Core/Element.h
  7. 1 2
      Include/RmlUi/Core/ElementUtilities.h
  8. 114 0
      Include/RmlUi/Core/FontEngineInterface.h
  9. 8 0
      Include/RmlUi/Core/GeometryUtilities.h
  10. 1 0
      Include/RmlUi/Core/Types.h
  11. 1 1
      Samples/basic/bitmapfont/src/main.cpp
  12. 14 1
      Samples/basic/demo/data/demo.rml
  13. 4 4
      Samples/basic/sdl2/src/main.cpp
  14. 4 4
      Samples/basic/sfml2/src/main.cpp
  15. 2 2
      Samples/shell/src/Shell.cpp
  16. 1 1
      Source/Controls/WidgetTextInput.cpp
  17. 1 1
      Source/Core/ComputeProperty.cpp
  18. 29 2
      Source/Core/Core.cpp
  19. 20 17
      Source/Core/DecoratorTiledBox.cpp
  20. 3 3
      Source/Core/Element.cpp
  21. 5 5
      Source/Core/ElementStyle.cpp
  22. 22 23
      Source/Core/ElementTextDefault.cpp
  23. 3 3
      Source/Core/ElementTextDefault.h
  24. 6 6
      Source/Core/ElementUtilities.cpp
  25. 19 33
      Source/Core/FontDatabaseDefault.cpp
  26. 12 28
      Source/Core/FontDatabaseDefault.h
  27. 0 1
      Source/Core/FontEffect.cpp
  28. 111 0
      Source/Core/FontEngineInterface.cpp
  29. 118 0
      Source/Core/FontEngineInterfaceDefault.cpp
  30. 112 0
      Source/Core/FontEngineInterfaceDefault.h
  31. 2 2
      Source/Core/FontFace.cpp
  32. 4 4
      Source/Core/FontFace.h
  33. 29 44
      Source/Core/FontFaceHandleDefault.cpp
  34. 11 3
      Source/Core/FontFaceHandleDefault.h
  35. 6 2
      Source/Core/FontFaceLayer.cpp
  36. 7 3
      Source/Core/FontFaceLayer.h
  37. 3 3
      Source/Core/FontFamily.cpp
  38. 3 3
      Source/Core/FontFamily.h
  39. 17 4
      Source/Core/FontProvider.cpp
  40. 7 5
      Source/Core/FontProvider.h
  41. 6 1
      Source/Core/FreeType/FontFace.cpp
  42. 7 3
      Source/Core/FreeType/FontFace.h
  43. 6 0
      Source/Core/FreeType/FontFaceHandle.cpp
  44. 6 2
      Source/Core/FreeType/FontFaceHandle.h
  45. 5 0
      Source/Core/FreeType/FontFamily.cpp
  46. 5 1
      Source/Core/FreeType/FontFamily.h
  47. 9 73
      Source/Core/FreeType/FontProvider.cpp
  48. 5 21
      Source/Core/FreeType/FontProvider.h
  49. 4 0
      Source/Core/FreeType/precompiled.h
  50. 31 0
      Source/Core/GeometryUtilities.cpp
  51. 20 20
      Source/Core/LayoutInlineBox.cpp
  52. 2 2
      Source/Core/LayoutInlineBox.h
  53. 6 6
      Source/Core/LayoutInlineBoxText.cpp
  54. 1 1
      Source/Core/LayoutLineBox.cpp
  55. 1 1
      Source/Core/Lua/RmlUi.cpp
  56. 5 2
      Source/Core/TextureResource.cpp
  57. 1 1
      Source/Debugger/BeaconSource.h
  58. 1 1
      Source/Debugger/CommonSource.h
  59. 1 1
      Source/Debugger/MenuSource.h
  60. 0 12
      Source/Debugger/Plugin.cpp
  61. 0 1
      Source/Debugger/Plugin.h

+ 15 - 1
.travis.yml

@@ -20,6 +20,20 @@ matrix:
             - libglew-dev
             - liblua5.2-dev
             - libsfml-dev
+    - os: linux
+      compiler: clang
+      env: NO_FONT_INTERFACE_DEFAULT="ON"
+      addons:
+        apt:
+          packages:
+            - cmake
+            - build-essential
+            - libsdl2-dev
+            - libsdl2-image-dev
+            - libfreetype6-dev
+            - libglew-dev
+            - liblua5.2-dev
+            - libsfml-dev
     - os: linux
       compiler: gcc
       env: VALGRIND_SAMPLES="1"
@@ -41,7 +55,7 @@ matrix:
 
 install:
   - cd "$TRAVIS_BUILD_DIR"
-  - if [[ "$TRAVIS_OS_NAME" != "osx" ]]; then cmake -DBUILD_LUA_BINDINGS=ON -DBUILD_SAMPLES=ON .; fi
+  - if [[ "$TRAVIS_OS_NAME" != "osx" ]]; then cmake -DBUILD_LUA_BINDINGS=ON -DBUILD_SAMPLES=ON -DNO_FONT_INTERFACE_DEFAULT=${NO_FONT_INTERFACE_DEFAULT:-OFF} .; fi
   - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then cmake -DNO_THIRDPARTY_CONTAINERS=ON -G Xcode .; fi
 
 before_script:

+ 12 - 8
CMake/FileList.cmake

@@ -31,15 +31,21 @@ set(Core_HDR_FILES
     ${PROJECT_SOURCE_DIR}/Source/Core/EventIterators.h
     ${PROJECT_SOURCE_DIR}/Source/Core/EventSpecification.h
     ${PROJECT_SOURCE_DIR}/Source/Core/FileInterfaceDefault.h
+    ${PROJECT_SOURCE_DIR}/Source/Core/FontDatabaseDefault.h
     ${PROJECT_SOURCE_DIR}/Source/Core/FontEffectOutline.h
     ${PROJECT_SOURCE_DIR}/Source/Core/FontEffectOutlineInstancer.h
     ${PROJECT_SOURCE_DIR}/Source/Core/FontEffectShadow.h
     ${PROJECT_SOURCE_DIR}/Source/Core/FontEffectShadowInstancer.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/FontFaceHandle.h
+    ${PROJECT_SOURCE_DIR}/Source/Core/FontEngineInterfaceDefault.h
+    ${PROJECT_SOURCE_DIR}/Source/Core/FontFace.h
+    ${PROJECT_SOURCE_DIR}/Source/Core/FontFaceHandleDefault.h
     ${PROJECT_SOURCE_DIR}/Source/Core/FontFaceLayer.h
+    ${PROJECT_SOURCE_DIR}/Source/Core/FontFamily.h
+    ${PROJECT_SOURCE_DIR}/Source/Core/FontProvider.h
     ${PROJECT_SOURCE_DIR}/Source/Core/FreeType/FontFace.h
     ${PROJECT_SOURCE_DIR}/Source/Core/FreeType/FontFaceHandle.h
     ${PROJECT_SOURCE_DIR}/Source/Core/FreeType/FontFamily.h
+    ${PROJECT_SOURCE_DIR}/Source/Core/FreeType/FontProvider.h
     ${PROJECT_SOURCE_DIR}/Source/Core/FreeType/precompiled.h
     ${PROJECT_SOURCE_DIR}/Source/Core/IdNameMap.h
     ${PROJECT_SOURCE_DIR}/Source/Core/LayoutBlockBox.h
@@ -129,14 +135,10 @@ set(Core_PUB_HDR_FILES
     ${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/FontDatabase.h
     ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/FontEffect.h
     ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/FontEffectInstancer.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/FontFace.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/FontFamily.h
+    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/FontEngineInterface.h
     ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/FontGlyph.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/FontProvider.h
-    ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/FreeType/FontProvider.h
     ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Geometry.h
     ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/GeometryUtilities.h
     ${PROJECT_SOURCE_DIR}/Include/RmlUi/Core/Header.h
@@ -237,15 +239,17 @@ set(Core_SRC_FILES
     ${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/FontDatabase.cpp
+    ${PROJECT_SOURCE_DIR}/Source/Core/FontDatabaseDefault.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/FontEffect.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/FontEffectInstancer.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/FontEffectOutline.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/FontEffectOutlineInstancer.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/FontEffectShadow.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/FontEffectShadowInstancer.cpp
+    ${PROJECT_SOURCE_DIR}/Source/Core/FontEngineInterface.cpp
+    ${PROJECT_SOURCE_DIR}/Source/Core/FontEngineInterfaceDefault.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/FontFace.cpp
-    ${PROJECT_SOURCE_DIR}/Source/Core/FontFaceHandle.cpp
+    ${PROJECT_SOURCE_DIR}/Source/Core/FontFaceHandleDefault.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/FontFaceLayer.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/FontFamily.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/FontProvider.cpp

+ 12 - 5
CMakeLists.txt

@@ -155,6 +155,11 @@ else(APPLE)
 	endif()
 endif(APPLE)
 
+option(NO_FONT_INTERFACE_DEFAULT "Do not build the font providers that come with the library" OFF)
+if(NO_FONT_INTERFACE_DEFAULT)
+	add_definitions(-DRMLUI_NO_FONT_INTERFACE_DEFAULT)
+endif()
+
 if(NOT BUILD_SHARED_LIBS)
 	add_definitions(-DRMLUI_STATIC_LIB)
 endif()
@@ -175,12 +180,14 @@ endif()
 #===================================
 
 # FreeType
-find_package(Freetype REQUIRED)	
+if(NOT NO_FONT_INTERFACE_DEFAULT)
+	find_package(Freetype REQUIRED)	
 
-if(FREETYPE_FOUND)
-	include_directories(${FREETYPE_INCLUDE_DIRS})
-	link_directories(${FREETYPE_LINK_DIRS})
-	list(APPEND CORE_LINK_LIBS ${FREETYPE_LIBRARY})
+	if(FREETYPE_FOUND)
+		include_directories(${FREETYPE_INCLUDE_DIRS})
+		link_directories(${FREETYPE_LINK_DIRS})
+		list(APPEND CORE_LINK_LIBS ${FREETYPE_LIBRARY})
+	endif()
 endif()
 
 #Lua

+ 1 - 3
Include/RmlUi/Core/ComputedValues.h

@@ -34,8 +34,6 @@
 namespace Rml {
 namespace Core {
 
-class FontFaceHandle;
-
 namespace Style
 {
 
@@ -176,7 +174,7 @@ struct ComputedValues
 	float font_size = 12.f;
 	// Font face used to render text and resolve ex properties. Does not represent a true property
 	// like most computed values, but placed here as it is used and inherited in a similar manner.
-	SharedPtr<FontFaceHandle> font_face_handle;
+	FontFaceHandle font_face_handle = 0;
 
 	TextAlign text_align = TextAlign::Left;
 	TextDecoration text_decoration = TextDecoration::None;

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

@@ -51,9 +51,9 @@
 #include "EventListenerInstancer.h"
 #include "Factory.h"
 #include "FileInterface.h"
-#include "FontDatabase.h"
 #include "FontEffect.h"
 #include "FontGlyph.h"
+#include "FontEngineInterface.h"
 #include "Geometry.h"
 #include "GeometryUtilities.h"
 #include "ID.h"
@@ -123,6 +123,11 @@ RMLUICORE_API void SetFileInterface(FileInterface* file_interface);
 /// Returns RmlUi's file interface.
 RMLUICORE_API FileInterface* GetFileInterface();
 
+// Sets the interface through which all font requests are made.
+RMLUICORE_API void SetFontEngineInterface(FontEngineInterface* _font_interface);
+// Returns RmlUi's file interface.
+RMLUICORE_API FontEngineInterface* GetFontEngineInterface();
+	
 /// Creates a new element context.
 /// @param[in] name The new name of the context. This must be unique.
 /// @param[in] dimensions The initial dimensions of the new context.

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

@@ -57,7 +57,7 @@ class ElementDocument;
 class ElementScroll;
 class ElementStyle;
 class PropertiesIteratorView;
-class FontFaceHandle;
+class FontFaceHandleDefault;
 class PropertyDictionary;
 class RenderInterface;
 class TransformState;
@@ -182,7 +182,7 @@ public:
 
 	/// Returns the element's font face handle.
 	/// @return The element's font face handle.
-	FontFaceHandle* GetFontFaceHandle() const;
+	FontFaceHandle GetFontFaceHandle() const;
 
 	/** @name Properties
 	 */

+ 1 - 2
Include/RmlUi/Core/ElementUtilities.h

@@ -37,7 +37,6 @@ namespace Rml {
 namespace Core {
 
 class Context;
-class FontFaceHandle;
 class RenderInterface;
 namespace Style { struct ComputedValues; }
 
@@ -81,7 +80,7 @@ public:
 	/// Returns an element's font face.
 	/// @param[in] element The element to determine the font face for.
 	/// @return The element's font face. This will be nullptr if no valid RCSS font styles have been set up for this element.
-	static SharedPtr<FontFaceHandle> GetFontFaceHandle(const Style::ComputedValues& computed_values);
+	static FontFaceHandle GetFontFaceHandle(const Style::ComputedValues& computed_values);
 	/// Returns an element's density-independent pixel ratio, defined by it's context
 	/// @param[in] element The element to determine the density-independent pixel ratio for.
 	/// @return The density-independent pixel ratio of the context, or 1.0 if no context assigned.

+ 114 - 0
Include/RmlUi/Core/FontEngineInterface.h

@@ -0,0 +1,114 @@
+/*
+ * This source file is part of RmlUi, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://github.com/mikke89/RmlUi
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#ifndef RMLUICOREFONTENGINEINTERFACE_H
+#define RMLUICOREFONTENGINEINTERFACE_H
+
+#include "Traits.h"
+#include "Header.h"
+#include "Types.h"
+#include "Geometry.h"
+
+namespace Rml {
+namespace Core {
+
+class RMLUICORE_API FontEngineInterface
+{
+public:
+	FontEngineInterface();
+	virtual ~FontEngineInterface();
+
+	/// Adds a new font face to the database. The face's family, style and weight will be determined from the face itself.
+	/// @param[in] file_name The file to load the face from.
+	/// @return True if the face was loaded successfully, false otherwise.
+	virtual bool LoadFontFace(const String& file_name);
+
+	/// Returns a handle to a font face that can be used to position and render text. This will return the closest match
+	/// it can find, but in the event a font family is requested that does not exist, NULL will be returned instead of a
+	/// valid handle.
+	/// @param[in] family The family of the desired font handle.
+	/// @param[in] style The style of the desired font handle.
+	/// @param[in] weight The weight of the desired font handle.
+	/// @param[in] size The size of desired handle, in points.
+	/// @return A valid handle if a matching (or closely matching) font face was found, NULL otherwise.
+	virtual FontFaceHandle GetFontFaceHandle(const String& family, Style::FontStyle style, Style::FontWeight weight, int size);
+
+	/// Generates, if required, the layer configuration for a given array of font effects.
+	/// @param[in] FontHandle
+	/// @param[in] font_effects The list of font effects to generate the configuration for.
+	/// @return The index to use when generating geometry using this configuration.
+	virtual int GenerateLayerConfiguration(FontFaceHandle, const FontEffectList &font_effects) const;
+
+	/// Returns the average advance of all glyphs in this font face.
+	/// @param[in] FontHandle
+	/// @return An approximate width of the characters in this font face.
+	virtual int GetCharacterWidth(FontFaceHandle) const;
+
+	/// Returns the point size of this font face.
+	/// @param[in] FontHandle
+	/// @return The face's point size.
+	virtual int GetSize(FontFaceHandle) const;
+	/// Returns the pixel height of a lower-case x in this font face.
+	/// @param[in] FontHandle
+	/// @return The height of a lower-case x.
+	virtual int GetXHeight(FontFaceHandle) const;
+	/// Returns the default height between this font face's baselines.
+	/// @param[in] FontHandle
+	/// @return The default line height.
+	virtual int GetLineHeight(FontFaceHandle) const;
+
+	/// Returns the font's baseline, as a pixel offset from the bottom of the font.
+	/// @param[in] FontHandle
+	/// @return The font's baseline.
+	virtual int GetBaseline(FontFaceHandle) const;
+
+	/// Returns the font's underline, as a pixel offset from the bottom of the font.
+	/// @param[in] FontHandle
+	/// @return The font's underline thickness.
+	virtual float GetUnderline(FontFaceHandle, float *thickness) const;
+
+	/// Returns the width a string will take up if rendered with this handle.
+	/// @param[in] FontHandle
+	/// @param[in] string The string to measure.
+	/// @param[in] prior_character The optionally-specified character that immediately precedes the string. This may have an impact on the string width due to kerning.
+	/// @return The width, in pixels, this string will occupy if rendered with this handle.
+	virtual int GetStringWidth(FontFaceHandle, const String& string, CodePoint prior_character = CodePoint::Null);
+
+	/// Generates the geometry required to render a single line of text.
+	/// @param[out] geometry An array of geometries to generate the geometry into.
+	/// @param[in] FontHandle
+	/// @param[in] string The string to render.
+	/// @param[in] position The position of the baseline of the first character to render.
+	/// @param[in] colour The colour to render the text.
+	/// @return The width, in pixels, of the string geometry.
+	virtual int GenerateString(FontFaceHandle, GeometryList& geometry, const String& string, const Vector2f& position, const Colourb& colour, int layer_configuration) const;
+};
+
+}
+}
+
+#endif

+ 8 - 0
Include/RmlUi/Core/GeometryUtilities.h

@@ -63,6 +63,14 @@ public:
 	/// @param[in] bottom_right_texcoord The texture coordinates at the bottom-right of the quad.
 	/// @param[in] index_offset The offset to be added to the generated indices; this should be the number of vertices already in the array.
 	static void GenerateQuad(Vertex* vertices, int* indices, const Vector2f& origin, const Vector2f& dimensions, const Colourb& colour, const Vector2f& top_left_texcoord, const Vector2f& bottom_right_texcoord, int index_offset = 0);
+	
+	/// Generates the geometry required to render a line above, below or through a line of text.
+	/// @param[out] geometry The geometry to append the newly created geometry into.
+	/// @param[in] position The position of the baseline of the lined text.
+	/// @param[in] width The width of the string to line.
+	/// @param[in] decoration_type The type for vertical positioning of line.
+	/// @param[in] colour The colour to draw the line in.
+	static void GenerateLine(FontFaceHandle font_face_handle, Geometry* geometry, const Vector2f& position, int width, Style::TextDecoration decoration_type, const Colourb& colour);
 
 private:
 	GeometryUtilities();

+ 1 - 0
Include/RmlUi/Core/Types.h

@@ -118,6 +118,7 @@ using FileHandle = uintptr_t;
 using TextureHandle = uintptr_t;
 using CompiledGeometryHandle = uintptr_t;
 using DecoratorDataHandle = uintptr_t;
+using FontFaceHandle = uintptr_t;
 
 // Strings
 using String = std::string;

+ 1 - 1
Samples/basic/bitmapfont/src/main.cpp

@@ -103,7 +103,7 @@ int main(int RMLUI_UNUSED_PARAMETER(argc), char** RMLUI_UNUSED_PARAMETER(argv))
 	shell_renderer->SetContext(context);
 
     // Load bitmap font
-    Rml::Core::FontDatabase::LoadFontFace("assets/Arial.fnt");
+    Rml::Core::GetFontEngineInterface()->LoadFontFace("assets/Arial.fnt");
 	
     // Load and show the demo document.
 	if(Rml::Core::ElementDocument* document = context->LoadDocument("assets/bitmapfont.rml"))

+ 14 - 1
Samples/basic/demo/data/demo.rml

@@ -122,6 +122,19 @@ button:focus {
 	font-size: 35px;
 }
 
+@decorator left-arrow : tiled-box {
+	top-image-src: ../../../assets/present.tga;
+	center-image-src: ../../../assets/present.tga;
+	left-image-src: ../../../assets/present.tga;
+}
+
+.left-arrow {
+	width: 32dp;
+	height: 32dp;
+	decorator: left-arrow;
+}
+
+
 </style>
 </head>
 
@@ -167,6 +180,6 @@ button:focus {
 	<textarea cols="30" rows="5" wrap="nowrap">Hello World!</textarea>
 </panel>
 </tabset>
-
+<div class="left-arrow"/>
 </body>
 </rml>

+ 4 - 4
Samples/basic/sdl2/src/main.cpp

@@ -89,10 +89,10 @@ int main(int argc, char **argv)
 	if(!Rml::Core::Initialise())
 		return 1;
 
-	Rml::Core::FontDatabase::LoadFontFace("assets/Delicious-Bold.otf");
-	Rml::Core::FontDatabase::LoadFontFace("assets/Delicious-BoldItalic.otf");
-	Rml::Core::FontDatabase::LoadFontFace("assets/Delicious-Italic.otf");
-	Rml::Core::FontDatabase::LoadFontFace("assets/Delicious-Roman.otf");
+	Rml::Core::GetFontEngineInterface()->LoadFontFace("assets/Delicious-Bold.otf");
+	Rml::Core::GetFontEngineInterface()->LoadFontFace("assets/Delicious-BoldItalic.otf");
+	Rml::Core::GetFontEngineInterface()->LoadFontFace("assets/Delicious-Italic.otf");
+	Rml::Core::GetFontEngineInterface()->LoadFontFace("assets/Delicious-Roman.otf");
 
 	Rml::Core::Context *Context = Rml::Core::CreateContext("default",
 		Rml::Core::Vector2i(window_width, window_height));

+ 4 - 4
Samples/basic/sfml2/src/main.cpp

@@ -89,10 +89,10 @@ int main(int argc, char **argv)
 	if(!Rml::Core::Initialise())
 		return 1;
 
-	Rml::Core::FontDatabase::LoadFontFace("assets/Delicious-Bold.otf");
-	Rml::Core::FontDatabase::LoadFontFace("assets/Delicious-BoldItalic.otf");
-	Rml::Core::FontDatabase::LoadFontFace("assets/Delicious-Italic.otf");
-	Rml::Core::FontDatabase::LoadFontFace("assets/Delicious-Roman.otf");
+	Rml::Core::GetFontEngineInterface()->LoadFontFace("assets/Delicious-Bold.otf");
+	Rml::Core::GetFontEngineInterface()->LoadFontFace("assets/Delicious-BoldItalic.otf");
+	Rml::Core::GetFontEngineInterface()->LoadFontFace("assets/Delicious-Italic.otf");
+	Rml::Core::GetFontEngineInterface()->LoadFontFace("assets/Delicious-Roman.otf");
 
 	Rml::Core::Context *Context = Rml::Core::CreateContext("default",
 		Rml::Core::Vector2i(MyWindow.getSize().x, MyWindow.getSize().y));

+ 2 - 2
Samples/shell/src/Shell.cpp

@@ -27,7 +27,7 @@
  */
 
 #include "Shell.h"
-#include <RmlUi/Core/FontDatabase.h>
+#include <RmlUi/Core/Core.h>
 
 /// Loads the default fonts from the given path.
 void Shell::LoadFonts(const char* directory)
@@ -41,7 +41,7 @@ void Shell::LoadFonts(const char* directory)
 
 	for (int i = 0; i < sizeof(font_names) / sizeof(Rml::Core::String); i++)
 	{
-		Rml::Core::FontDatabase::LoadFontFace(Rml::Core::String(directory) + font_names[i]);
+		Rml::Core::GetFontEngineInterface()->LoadFontFace(Rml::Core::String(directory) + font_names[i]);
 	}
 }
 

+ 1 - 1
Source/Controls/WidgetTextInput.cpp

@@ -999,7 +999,7 @@ void WidgetTextInput::GenerateCursor()
 
 void WidgetTextInput::UpdateCursorPosition()
 {
-	if (text_element->GetFontFaceHandle() == nullptr)
+	if (text_element->GetFontFaceHandle() == 0)
 		return;
 
 	cursor_position.x = (float) Core::ElementUtilities::GetStringWidth(text_element, lines[cursor_line_index].content.substr(0, cursor_character_index));

+ 1 - 1
Source/Core/ComputeProperty.cpp

@@ -33,7 +33,7 @@ namespace Rml {
 namespace Core {
 
 
-const Style::ComputedValues DefaultComputedValues;
+const Style::ComputedValues DefaultComputedValues = Style::ComputedValues{};
 
 static constexpr float PixelsPerInch = 96.0f;
 

+ 29 - 2
Source/Core/Core.cpp

@@ -30,6 +30,7 @@
 #include "../../Include/RmlUi/Core.h"
 #include "EventSpecification.h"
 #include "FileInterfaceDefault.h"
+#include "FontEngineInterfaceDefault.h"
 #include "PluginRegistry.h"
 #include "StyleSheetFactory.h"
 #include "TemplateCache.h"
@@ -45,10 +46,14 @@ static RenderInterface* render_interface = nullptr;
 static SystemInterface* system_interface = nullptr;
 // RmlUi's file I/O interface.
 static FileInterface* file_interface = nullptr;
+// RmlUi's font engine interface.
+static FontEngineInterface* font_interface = nullptr;
 
 // Default interfaces should be created and destroyed on Initialise and Shutdown, respectively.
 static UniquePtr<FileInterface> default_file_interface;
 
+static UniquePtr<FontEngineInterface> default_font_interface;
+
 static bool initialised = false;
 
 using ContextMap = UnorderedMap< String, ContextPtr >;
@@ -85,7 +90,16 @@ bool Initialise()
 
 	TextureDatabase::Initialise();
 
-	FontDatabase::Initialise();
+	if (!font_interface)
+	{
+#ifndef RMLUI_NO_FONT_INTERFACE_DEFAULT
+		default_font_interface = std::make_unique<FontEngineInterfaceDefault>();
+		font_interface = default_font_interface.get();
+#else
+		Log::Message(Log::LT_ERROR, "No font interface set!");
+		return false;
+#endif
+	}
 
 	StyleSheetSpecification::Initialise();
 	StyleSheetFactory::Initialise();
@@ -113,7 +127,6 @@ void Shutdown()
 	TemplateCache::Shutdown();
 	StyleSheetFactory::Shutdown();
 	StyleSheetSpecification::Shutdown();
-	FontDatabase::Shutdown();
 	TextureDatabase::Shutdown();
 	Factory::Shutdown();
 
@@ -124,8 +137,10 @@ void Shutdown()
 	render_interface = nullptr;
 	file_interface = nullptr;
 	system_interface = nullptr;
+	font_interface = nullptr;
 
 	default_file_interface.reset();
+	default_font_interface.reset();
 }
 
 // Returns the version of this RmlUi library.
@@ -170,6 +185,18 @@ FileInterface* GetFileInterface()
 	return file_interface;
 }
 
+// Sets the interface through which all font requests are made.
+void SetFontEngineInterface(FontEngineInterface* _font_interface)
+{
+	font_interface = _font_interface;
+}
+	
+// Returns RmlUi's file interface.
+FontEngineInterface* GetFontEngineInterface()
+{
+	return font_interface;
+}
+
 // Creates a new element context.
 Context* CreateContext(const String& name, const Vector2i& dimensions, RenderInterface* custom_render_interface)
 {

+ 20 - 17
Source/Core/DecoratorTiledBox.cpp

@@ -70,6 +70,16 @@ bool DecoratorTiledBox::Initialise(const Tile* _tiles, const Texture* _textures)
 		tiles[i].texture_index = AddTexture(_textures[i]);
 	}
 
+	// All corners must have a valid texture.
+	for (int i = TOP_LEFT_CORNER; i <= BOTTOM_RIGHT_CORNER; i++)
+	{
+		if (tiles[i].texture_index == -1)
+			return false;
+	}
+	// Check that the centre tile has been specified.
+	if (tiles[CENTRE].texture_index < 0)
+		return false;
+
 	// If only one side of the left / right edges have been configured, then mirror the tile for the other side.
 	if (tiles[LEFT_EDGE].texture_index == -1 && tiles[RIGHT_EDGE].texture_index > -1)
 	{
@@ -98,10 +108,6 @@ bool DecoratorTiledBox::Initialise(const Tile* _tiles, const Texture* _textures)
 	else if (tiles[TOP_EDGE].texture_index == -1 && tiles[BOTTOM_EDGE].texture_index == -1)
 		return false;
 
-	// Check that the centre tile has been specified.
-	if (tiles[CENTRE].texture_index < 0)
-		return false;
-
 	return true;
 }
 
@@ -255,19 +261,16 @@ DecoratorDataHandle DecoratorTiledBox::GenerateElementData(Element* element) con
 												bottom_right_dimensions);
 
 	// Generate the centre geometry.
-	if (tiles[CENTRE].texture_index >= 0)
-	{
-		Vector2f centre_dimensions = tiles[CENTRE].GetDimensions(element);
-		Vector2f centre_surface_dimensions(padded_size.x - (left_dimensions.x + right_dimensions.x),
-											  padded_size.y - (top_dimensions.y + bottom_dimensions.y));
-
-		tiles[CENTRE].GenerateGeometry(data->geometry[tiles[CENTRE].texture_index].GetVertices(),
-									   data->geometry[tiles[CENTRE].texture_index].GetIndices(),
-									   element,
-									   Vector2f(left_dimensions.x, top_dimensions.y),
-									   centre_surface_dimensions,
-									   centre_dimensions);
-	}
+	Vector2f centre_dimensions = tiles[CENTRE].GetDimensions(element);
+	Vector2f centre_surface_dimensions(padded_size.x - (left_dimensions.x + right_dimensions.x),
+											padded_size.y - (top_dimensions.y + bottom_dimensions.y));
+
+	tiles[CENTRE].GenerateGeometry(data->geometry[tiles[CENTRE].texture_index].GetVertices(),
+									data->geometry[tiles[CENTRE].texture_index].GetIndices(),
+									element,
+									Vector2f(left_dimensions.x, top_dimensions.y),
+									centre_surface_dimensions,
+									centre_dimensions);
 
 	// Set the textures on the geometry.
 	const Texture* texture = nullptr;

+ 3 - 3
Source/Core/Element.cpp

@@ -45,7 +45,7 @@
 #include "EventDispatcher.h"
 #include "EventSpecification.h"
 #include "ElementDecoration.h"
-#include "FontFaceHandle.h"
+#include "FontFaceHandleDefault.h"
 #include "LayoutEngine.h"
 #include "PluginRegistry.h"
 #include "PropertiesIterator.h"
@@ -574,9 +574,9 @@ float Element::GetZIndex() const
 }
 
 // Returns the element's font face handle.
-FontFaceHandle* Element::GetFontFaceHandle() const
+FontFaceHandle Element::GetFontFaceHandle() const
 {
-	return element_meta->computed_values.font_face_handle.get();
+	return element_meta->computed_values.font_face_handle;
 }
 
 // Sets a local property override on the element.

+ 5 - 5
Source/Core/ElementStyle.cpp

@@ -43,7 +43,7 @@
 #include "ElementBorder.h"
 #include "ElementDecoration.h"
 #include "ElementDefinition.h"
-#include "FontFaceHandle.h"
+#include "FontFaceHandleDefault.h"
 #include "ComputeProperty.h"
 #include "PropertiesIterator.h"
 
@@ -744,19 +744,19 @@ PropertyIdSet ElementStyle::ComputeValues(Style::ComputedValues& values, const S
 
 		case PropertyId::FontFamily:
 			values.font_family = StringUtilities::ToLower(p->Get<String>());
-			values.font_face_handle.reset();
+			values.font_face_handle = 0;
 			break;
 		case PropertyId::FontStyle:
 			values.font_style = (FontStyle)p->Get< int >();
-			values.font_face_handle.reset();
+			values.font_face_handle = 0;
 			break;
 		case PropertyId::FontWeight:
 			values.font_weight = (FontWeight)p->Get< int >();
-			values.font_face_handle.reset();
+			values.font_face_handle = 0;
 			break;
 		case PropertyId::FontSize:
 			// (font-size computed above)
-			values.font_face_handle.reset();
+			values.font_face_handle = 0;
 			break;
 
 		case PropertyId::TextAlign:

+ 22 - 23
Source/Core/ElementTextDefault.cpp

@@ -30,11 +30,10 @@
 #include "ElementTextDefault.h"
 #include "ElementDefinition.h"
 #include "ElementStyle.h"
-#include "FontFaceHandle.h"
+#include "FontFaceHandleDefault.h"
 #include "../../Include/RmlUi/Core/ElementDocument.h"
 #include "../../Include/RmlUi/Core/ElementUtilities.h"
 #include "../../Include/RmlUi/Core/Event.h"
-#include "../../Include/RmlUi/Core/FontDatabase.h"
 #include "../../Include/RmlUi/Core/Property.h"
 
 namespace Rml {
@@ -80,8 +79,8 @@ void ElementTextDefault::OnRender()
 {
 	RMLUI_ZoneScoped;
 
-	FontFaceHandle* font_face_handle = GetFontFaceHandle();
-	if (!font_face_handle)
+	FontFaceHandle font_face_handle = GetFontFaceHandle();
+	if (font_face_handle == 0)
 		return;
 	
 	
@@ -108,7 +107,7 @@ void ElementTextDefault::OnRender()
 		float clip_left = (float)clip_origin.x;
 		float clip_right = (float)(clip_origin.x + clip_dimensions.x);
 		float clip_bottom = (float)(clip_origin.y + clip_dimensions.y);
-		float line_height = (float)GetFontFaceHandle()->GetLineHeight();
+		float line_height = (float)GetFontEngineInterface()->GetLineHeight(GetFontFaceHandle());
 		
 		render = false;
 		for (size_t i = 0; i < lines.size(); ++i)
@@ -149,8 +148,8 @@ bool ElementTextDefault::GenerateToken(float& token_width, int line_begin)
 	RMLUI_ZoneScoped;
 
 	// Bail if we don't have a valid font face.
-	FontFaceHandle* font_face_handle = GetFontFaceHandle();
-	if (font_face_handle == nullptr ||
+	FontFaceHandle font_face_handle = GetFontFaceHandle();
+	if (font_face_handle == 0 ||
 		line_begin >= (int) text.size())
 		return 0;
 
@@ -169,7 +168,7 @@ bool ElementTextDefault::GenerateToken(float& token_width, int line_begin)
 	String token;
 
 	BuildToken(token, token_begin, text.c_str() + text.size(), true, collapse_white_space, break_at_endline, computed.text_transform);
-	token_width = (float) font_face_handle->GetStringWidth(token);
+	token_width = (float) GetFontEngineInterface()->GetStringWidth(font_face_handle, token);
 
 	return LastToken(token_begin, text.c_str() + text.size(), collapse_white_space, break_at_endline);
 }
@@ -179,7 +178,7 @@ bool ElementTextDefault::GenerateLine(String& line, int& line_length, float& lin
 {
 	RMLUI_ZoneScoped;
 
-	FontFaceHandle* font_face_handle = GetFontFaceHandle();
+	FontFaceHandle font_face_handle = GetFontFaceHandle();
 
 	// Initialise the output variables.
 	line.clear();
@@ -187,7 +186,7 @@ bool ElementTextDefault::GenerateLine(String& line, int& line_length, float& lin
 	line_width = 0;
 
 	// Bail if we don't have a valid font face.
-	if (font_face_handle == nullptr)
+	if (font_face_handle == 0)
 		return true;
 
 	// Determine how we are processing white-space while formatting the text.
@@ -223,7 +222,7 @@ bool ElementTextDefault::GenerateLine(String& line, int& line_length, float& lin
 
 		// Generate the next token and determine its pixel-length.
 		bool break_line = BuildToken(token, next_token_begin, string_end, line.empty() && trim_whitespace_prefix, collapse_white_space, break_at_endline, text_transform_property);
-		int token_width = font_face_handle->GetStringWidth(token, previous_codepoint);
+		int token_width = GetFontEngineInterface()->GetStringWidth(font_face_handle, token, previous_codepoint);
 
 		// If we're breaking to fit a line box, check if the token can fit on the line before we add it.
 		if (break_at_line)
@@ -267,15 +266,15 @@ void ElementTextDefault::ClearLines()
 // Adds a new line into the text element.
 void ElementTextDefault::AddLine(const Vector2f& line_position, const String& line)
 {
-	FontFaceHandle* font_face_handle = GetFontFaceHandle();
+	FontFaceHandle font_face_handle = GetFontFaceHandle();
 
-	if (font_face_handle == nullptr)
+	if (font_face_handle == 0)
 		return;
 
 	if (font_dirty)
 		UpdateFontConfiguration();
 
-	Vector2f baseline_position = line_position + Vector2f(0.0f, (float) font_face_handle->GetLineHeight() - font_face_handle->GetBaseline());
+	Vector2f baseline_position = line_position + Vector2f(0.0f, (float)GetFontEngineInterface()->GetLineHeight(font_face_handle) - GetFontEngineInterface()->GetBaseline(font_face_handle));
 	lines.push_back(Line(line, baseline_position));
 
 	geometry_dirty = true;
@@ -329,8 +328,8 @@ void ElementTextDefault::OnPropertyChange(const PropertyIdSet& changed_propertie
 			{
 				decoration.Release(true);
 
-				FontFaceHandle* font_face_handle = GetFontFaceHandle();
-				if (font_face_handle != nullptr)
+				FontFaceHandle font_face_handle = GetFontFaceHandle();
+				if (font_face_handle != 0)
 				{
 					for (size_t i = 0; i < lines.size(); ++i)
 						GenerateDecoration(font_face_handle, lines[i]);
@@ -372,7 +371,7 @@ bool ElementTextDefault::UpdateFontConfiguration()
 {
 	RMLUI_ZoneScoped;
 
-	if (GetFontFaceHandle() == nullptr)
+	if (GetFontFaceHandle() == 0)
 		return false;
 
 	font_dirty = false;
@@ -386,7 +385,7 @@ bool ElementTextDefault::UpdateFontConfiguration()
 
 	// Request a font layer configuration to match this set of effects. If this is different from
 	// our old configuration, then return true to indicate we'll need to regenerate geometry.
-	int new_configuration = GetFontFaceHandle()->GenerateLayerConfiguration(*font_effects);
+	int new_configuration = GetFontEngineInterface()->GenerateLayerConfiguration(GetFontFaceHandle(), *font_effects);
 	if (new_configuration != font_configuration)
 	{
 		font_configuration = new_configuration;
@@ -397,7 +396,7 @@ bool ElementTextDefault::UpdateFontConfiguration()
 }
 
 // Clears and regenerates all of the text's geometry.
-void ElementTextDefault::GenerateGeometry(const FontFaceHandle* font_face_handle)
+void ElementTextDefault::GenerateGeometry(const FontFaceHandle font_face_handle)
 {
 	RMLUI_ZoneScopedC(0xD2691E);
 
@@ -412,9 +411,9 @@ void ElementTextDefault::GenerateGeometry(const FontFaceHandle* font_face_handle
 	geometry_dirty = false;
 }
 
-void ElementTextDefault::GenerateGeometry(const FontFaceHandle* font_face_handle, Line& line)
+void ElementTextDefault::GenerateGeometry(const FontFaceHandle font_face_handle, Line& line)
 {
-	line.width = font_face_handle->GenerateString(geometry, line.text, line.position, colour, font_configuration);
+	line.width = GetFontEngineInterface()->GenerateString(font_face_handle, geometry, line.text, line.position, colour, font_configuration);
 	for (size_t i = 0; i < geometry.size(); ++i)
 		geometry[i].SetHostElement(this);
 
@@ -423,11 +422,11 @@ void ElementTextDefault::GenerateGeometry(const FontFaceHandle* font_face_handle
 }
 
 // Generates any geometry necessary for rendering a line decoration (underline, strike-through, etc).
-void ElementTextDefault::GenerateDecoration(const FontFaceHandle* font_face_handle, const Line& line)
+void ElementTextDefault::GenerateDecoration(const FontFaceHandle font_face_handle, const Line& line)
 {
 	RMLUI_ZoneScopedC(0xA52A2A);
 	
-	font_face_handle->GenerateLine(&decoration, line.position, line.width, decoration_property, colour);
+	GeometryUtilities::GenerateLine(font_face_handle, &decoration, line.position, line.width, decoration_property, colour);
 }
 
 static bool BuildToken(String& token, const char*& token_begin, const char* string_end, bool first_token, bool collapse_white_space, bool break_at_endline, Style::TextTransform text_transformation)

+ 3 - 3
Source/Core/ElementTextDefault.h

@@ -103,11 +103,11 @@ private:
 	};
 
 	// Clears and regenerates all of the text's geometry.
-	void GenerateGeometry(const FontFaceHandle* font_face_handle);
+	void GenerateGeometry(const FontFaceHandle font_face_handle);
 	// Generates the geometry for a single line of text.
-	void GenerateGeometry(const FontFaceHandle* font_face_handle, Line& line);
+	void GenerateGeometry(const FontFaceHandle font_face_handle, Line& line);
 	// Generates any geometry necessary for rendering a line decoration (underline, strike-through, etc).
-	void GenerateDecoration(const FontFaceHandle* font_face_handle, const Line& line);
+	void GenerateDecoration(const FontFaceHandle font_face_handle, const Line& line);
 
 	String text;
 

+ 6 - 6
Source/Core/ElementUtilities.cpp

@@ -32,7 +32,7 @@
 #include "../../Include/RmlUi/Core/ElementUtilities.h"
 #include <queue>
 #include <limits>
-#include "FontFaceHandle.h"
+#include "FontFaceHandleDefault.h"
 #include "LayoutEngine.h"
 #include "ElementStyle.h"
 
@@ -139,13 +139,13 @@ void ElementUtilities::GetElementsByClassName(ElementList& elements, Element* ro
 }
 
 // Returns the element's font face.
-SharedPtr<FontFaceHandle> ElementUtilities::GetFontFaceHandle(const Style::ComputedValues& computed_values)
+FontFaceHandle ElementUtilities::GetFontFaceHandle(const Style::ComputedValues& computed_values)
 {
 	RMLUI_ZoneScoped;
 	
 	int font_size = (int)computed_values.font_size;
 
-	return FontDatabase::GetFontFaceHandle(computed_values.font_family, computed_values.font_style, computed_values.font_weight, font_size);
+	return GetFontEngineInterface()->GetFontFaceHandle(computed_values.font_family, computed_values.font_style, computed_values.font_weight, font_size);
 }
 
 float ElementUtilities::GetDensityIndependentPixelRatio(Element * element)
@@ -160,11 +160,11 @@ float ElementUtilities::GetDensityIndependentPixelRatio(Element * element)
 // Returns the width of a string rendered within the context of the given element.
 int ElementUtilities::GetStringWidth(Element* element, const String& string)
 {
-	FontFaceHandle* font_face_handle = element->GetFontFaceHandle();
-	if (font_face_handle == nullptr)
+	FontFaceHandle font_face_handle = element->GetFontFaceHandle();
+	if (font_face_handle == 0)
 		return 0;
 
-	return font_face_handle->GetStringWidth(string);
+	return GetFontEngineInterface()->GetStringWidth(font_face_handle, string);
 }
 
 void ElementUtilities::BindEventAttributes(Element* element)

+ 19 - 33
Source/Core/FontDatabase.cpp → Source/Core/FontDatabaseDefault.cpp

@@ -27,34 +27,36 @@
  */
 
 #include "precompiled.h"
-#include <RmlUi/Core/FontDatabase.h>
-#include <RmlUi/Core/FontFamily.h>
 #include <RmlUi/Core.h>
-#include <RmlUi/Core/FreeType/FontProvider.h>
+#include "FontFamily.h"
+#include "FreeType/FontProvider.h"
+#include "FontDatabaseDefault.h"
 
 namespace Rml {
 namespace Core {
 
-FontDatabase* FontDatabase::instance = nullptr;
-FontDatabase::FontProviderTable FontDatabase::font_provider_table;
+#ifndef RMLUI_NO_FONT_INTERFACE_DEFAULT
 
-FontDatabase::FontDatabase()
+FontDatabaseDefault* FontDatabaseDefault::instance = nullptr;
+FontDatabaseDefault::FontProviderTable FontDatabaseDefault::font_provider_table;
+
+FontDatabaseDefault::FontDatabaseDefault()
 {
 	RMLUI_ASSERT(instance == nullptr);
 	instance = this;
 }
 
-FontDatabase::~FontDatabase()
+FontDatabaseDefault::~FontDatabaseDefault()
 {
 	RMLUI_ASSERT(instance == this);
 	instance = nullptr;
 }
 
-bool FontDatabase::Initialise()
+bool FontDatabaseDefault::Initialise()
 {
 	if (instance == nullptr)
 	{
-		new FontDatabase();
+		new FontDatabaseDefault();
 
         if(!FontProvider_FreeType::Initialise())
             return false;
@@ -63,7 +65,7 @@ bool FontDatabase::Initialise()
 	return true;
 }
 
-void FontDatabase::Shutdown()
+void FontDatabaseDefault::Shutdown()
 {
 	if (instance != nullptr)
 	{
@@ -74,37 +76,19 @@ void FontDatabase::Shutdown()
 }
 
 // Loads a new font face.
-bool FontDatabase::LoadFontFace(const String& file_name)
+bool FontDatabaseDefault::LoadFontFace(const String& file_name)
 {
 	return FontProvider_FreeType::LoadFontFace(file_name);
 }
 
-// Adds a new font face to the database, ignoring any family, style and weight information stored in the face itself.
-bool FontDatabase::LoadFontFace(const String& file_name, const String& family, Style::FontStyle style, Style::FontWeight weight)
-{
-	return FontProvider_FreeType::LoadFontFace(file_name, family, style, weight);
-}
-
-// Adds a new font face to the database, loading from memory.
-bool FontDatabase::LoadFontFace(const byte* data, int data_length)
-{
-	return FontProvider_FreeType::LoadFontFace(data, data_length);
-}
-
-// Adds a new font face to the database, loading from memory, ignoring any family, style and weight information stored in the face itself.
-bool FontDatabase::LoadFontFace(const byte* data, int data_length, const String& family, Style::FontStyle style, Style::FontWeight weight)
-{
-	return FontProvider_FreeType::LoadFontFace(data, data_length, family, style, weight);
-}
-
 // Returns a handle to a font face that can be used to position and render text.
-SharedPtr<FontFaceHandle> FontDatabase::GetFontFaceHandle(const String& family, Style::FontStyle style, Style::FontWeight weight, int size)
+SharedPtr<FontFaceHandleDefault> FontDatabaseDefault::GetFontFaceHandle(const String& family, Style::FontStyle style, Style::FontWeight weight, int size)
 {
     size_t provider_count = font_provider_table.size();
 
     for(size_t provider_index = 0; provider_index < provider_count; ++provider_index)
     {
-		SharedPtr<FontFaceHandle> face_handle = font_provider_table[ provider_index ]->GetFontFaceHandle(family, style, weight, size);
+		SharedPtr<FontFaceHandleDefault> face_handle = font_provider_table[ provider_index ]->GetFontFaceHandle(family, style, weight, size);
 
         if(face_handle)
             return face_handle;
@@ -113,12 +97,12 @@ SharedPtr<FontFaceHandle> FontDatabase::GetFontFaceHandle(const String& family,
     return nullptr;
 }
 
-void FontDatabase::AddFontProvider(FontProvider * provider)
+void FontDatabaseDefault::AddFontProvider(FontProvider * provider)
 {
     instance->font_provider_table.push_back(provider);
 }
 
-void FontDatabase::RemoveFontProvider(FontProvider * provider)
+void FontDatabaseDefault::RemoveFontProvider(FontProvider * provider)
 {
     for(FontProviderTable::iterator i = instance->font_provider_table.begin(); i != instance->font_provider_table.end(); ++i)
     {
@@ -130,5 +114,7 @@ void FontDatabase::RemoveFontProvider(FontProvider * provider)
     }
 }
 
+#endif
+
 }
 }

+ 12 - 28
Include/RmlUi/Core/FontDatabase.h → Source/Core/FontDatabaseDefault.h

@@ -29,16 +29,18 @@
 #ifndef RMLUICOREFONTDATABASE_H
 #define RMLUICOREFONTDATABASE_H
 
-#include "StringUtilities.h"
-#include "Header.h"
+#include <RmlUi/Core/StringUtilities.h>
+#include <RmlUi/Core/Header.h>
 #include "FontProvider.h"
 
 namespace Rml {
 namespace Core {
 
+#ifndef RMLUI_NO_FONT_INTERFACE_DEFAULT
+
 class FontEffect;
 class FontFamily;
-class FontFaceHandle;
+class FontFaceHandleDefault;
 class PropertyDictionary;
 
 /**
@@ -47,7 +49,7 @@ class PropertyDictionary;
 	@author Peter Curry
  */
 
-class RMLUICORE_API FontDatabase
+class RMLUICORE_API FontDatabaseDefault
 {
 public:
 	static bool Initialise();
@@ -57,26 +59,6 @@ public:
 	/// @param[in] file_name The file to load the face from.
 	/// @return True if the face was loaded successfully, false otherwise.
 	static bool LoadFontFace(const String& file_name);
-	/// Adds a new font face to the database, ignoring any family, style and weight information stored in the face itself.
-	/// @param[in] file_name The file to load the face from.
-	/// @param[in] family The family to add the face to.
-	/// @param[in] style The style of the face (normal or italic).
-	/// @param[in] weight The weight of the face (normal or bold).
-	/// @return True if the face was loaded successfully, false otherwise.
-	static bool LoadFontFace(const String& file_name, const String& family, Style::FontStyle style, Style::FontWeight weight);
-	/// Adds a new font face to the database, loading from memory. The face's family, style and weight will be determined from the face itself.
-	/// @param[in] data The font data.
-	/// @param[in] data_length Length of the data.
-	/// @return True if the face was loaded successfully, false otherwise.
-    static bool LoadFontFace(const byte* data, int data_length);
-	/// Adds a new font face to the database, loading from memory.
-	/// @param[in] data The font data.
-	/// @param[in] data_length Length of the data.
-	/// @param[in] family The family to add the face to.
-	/// @param[in] style The style of the face (normal or italic).
-	/// @param[in] weight The weight of the face (normal or bold).
-	/// @return True if the face was loaded successfully, false otherwise.
-    static bool LoadFontFace(const byte* data, int data_length, const String& family, Style::FontStyle style, Style::FontWeight weight);
 
 	/// Returns a handle to a font face that can be used to position and render text. This will return the closest match
 	/// it can find, but in the event a font family is requested that does not exist, nullptr will be returned instead of a
@@ -86,22 +68,24 @@ public:
 	/// @param[in] weight The weight of the desired font handle.
 	/// @param[in] size The size of desired handle, in points.
 	/// @return A valid handle if a matching (or closely matching) font face was found, nullptr otherwise.
-	static SharedPtr<FontFaceHandle> GetFontFaceHandle(const String& family, Style::FontStyle style, Style::FontWeight weight, int size);
+	static SharedPtr<FontFaceHandleDefault> GetFontFaceHandle(const String& family, Style::FontStyle style, Style::FontWeight weight, int size);
 
     static void AddFontProvider(FontProvider * provider);
 
     static void RemoveFontProvider(FontProvider * provider);
 
 private:
-	FontDatabase(void);
-	~FontDatabase(void);
+	FontDatabaseDefault(void);
+	~FontDatabaseDefault(void);
 
     typedef std::vector< FontProvider *> FontProviderTable;
 
     static FontProviderTable font_provider_table;
-	static FontDatabase* instance;
+	static FontDatabaseDefault* instance;
 };
 
+#endif
+
 }
 }
 

+ 0 - 1
Source/Core/FontEffect.cpp

@@ -28,7 +28,6 @@
 
 #include "precompiled.h"
 #include "../../Include/RmlUi/Core/FontEffect.h"
-#include "../../Include/RmlUi/Core/FontDatabase.h"
 #include "../../Include/RmlUi/Core/FontEffectInstancer.h"
 
 namespace Rml {

+ 111 - 0
Source/Core/FontEngineInterface.cpp

@@ -0,0 +1,111 @@
+/*
+ * This source file is part of RmlUi, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://github.com/mikke89/RmlUi
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ * Copyright (c) 2019 The RmlUi Team, and contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include "precompiled.h"
+
+namespace Rml {
+namespace Core {
+
+FontEngineInterface::FontEngineInterface()
+{
+}
+
+FontEngineInterface::~FontEngineInterface()
+{
+}
+
+bool FontEngineInterface::LoadFontFace(const String& file_name)
+{
+	return false;
+}
+
+FontFaceHandle FontEngineInterface::GetFontFaceHandle(const String& RMLUI_UNUSED_PARAMETER(family), Style::FontStyle RMLUI_UNUSED_PARAMETER(style),
+	Style::FontWeight RMLUI_UNUSED_PARAMETER(weight), int RMLUI_UNUSED_PARAMETER(size))
+{
+	RMLUI_UNUSED(family);
+	RMLUI_UNUSED(style);
+	RMLUI_UNUSED(weight);
+	RMLUI_UNUSED(size);
+	return 0;
+}
+	
+int FontEngineInterface::GenerateLayerConfiguration(FontFaceHandle, const FontEffectList& font_effects) const
+{
+	return 0;
+}
+
+int FontEngineInterface::GetCharacterWidth(FontFaceHandle) const
+{
+	return 0;
+}
+
+int FontEngineInterface::GetSize(FontFaceHandle) const
+{
+	return 0;
+}
+
+int FontEngineInterface::GetXHeight(FontFaceHandle) const
+{
+	return 0;
+}
+
+int FontEngineInterface::GetLineHeight(FontFaceHandle) const
+{
+	return 0;
+}
+
+int FontEngineInterface::GetBaseline(FontFaceHandle) const
+{
+	return 0;
+}
+
+float FontEngineInterface::GetUnderline(FontFaceHandle, float *) const
+{
+	return 0;
+}
+
+int FontEngineInterface::GetStringWidth(FontFaceHandle, const String& RMLUI_UNUSED_PARAMETER(string), CodePoint RMLUI_UNUSED_PARAMETER(prior_character))
+{
+	RMLUI_UNUSED(string);
+	RMLUI_UNUSED(prior_character);
+	return 0;
+}
+
+int FontEngineInterface::GenerateString(FontFaceHandle, GeometryList& RMLUI_UNUSED_PARAMETER(geometry), const String& RMLUI_UNUSED_PARAMETER(string), 
+	const Vector2f& RMLUI_UNUSED_PARAMETER(position), const Colourb& RMLUI_UNUSED_PARAMETER(colour), int RMLUI_UNUSED_PARAMETER(layer_configuration)) const
+{
+	RMLUI_UNUSED(geometry);
+	RMLUI_UNUSED(string);
+	RMLUI_UNUSED(position);
+	RMLUI_UNUSED(colour);
+	RMLUI_UNUSED(layer_configuration);
+	return 0;
+}
+
+}
+}

+ 118 - 0
Source/Core/FontEngineInterfaceDefault.cpp

@@ -0,0 +1,118 @@
+/*
+ * This source file is part of RmlUi, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://github.com/mikke89/RmlUi
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ * Copyright (c) 2019 The RmlUi Team, and contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include "precompiled.h"
+#include "FontDatabaseDefault.h"
+#include "FontFaceHandleDefault.h"
+#include "FontEngineInterfaceDefault.h"
+
+namespace Rml {
+namespace Core {
+
+#ifndef RMLUI_NO_FONT_INTERFACE_DEFAULT
+
+FontEngineInterfaceDefault::FontEngineInterfaceDefault()
+{
+	FontDatabaseDefault::Initialise();
+}
+
+FontEngineInterfaceDefault::~FontEngineInterfaceDefault()
+{
+	FontDatabaseDefault::Shutdown();
+}
+
+bool FontEngineInterfaceDefault::LoadFontFace(const String& file_name)
+{
+	return FontDatabaseDefault::LoadFontFace(file_name);
+}
+
+FontFaceHandle FontEngineInterfaceDefault::GetFontFaceHandle(const String& family, Style::FontStyle style, Style::FontWeight weight, int size)
+{
+	auto handle = FontDatabaseDefault::GetFontFaceHandle(family, style, weight, size);
+	return reinterpret_cast<FontFaceHandle>(handle.get());
+}
+	
+int FontEngineInterfaceDefault::GenerateLayerConfiguration(FontFaceHandle handle, const FontEffectList& font_effects) const
+{
+	auto handle_default = reinterpret_cast<FontFaceHandleDefault *>(handle);
+	return handle_default->GenerateLayerConfiguration(font_effects);
+}
+
+int FontEngineInterfaceDefault::GetCharacterWidth(FontFaceHandle handle) const
+{
+	auto handle_default = reinterpret_cast<FontFaceHandleDefault *>(handle);
+	return handle_default->GetCharacterWidth();
+}
+
+int FontEngineInterfaceDefault::GetSize(FontFaceHandle handle) const
+{
+	auto handle_default = reinterpret_cast<FontFaceHandleDefault *>(handle);
+	return handle_default->GetSize();
+}
+
+int FontEngineInterfaceDefault::GetXHeight(FontFaceHandle handle) const
+{
+	auto handle_default = reinterpret_cast<FontFaceHandleDefault *>(handle);
+	return handle_default->GetXHeight();
+}
+
+int FontEngineInterfaceDefault::GetLineHeight(FontFaceHandle handle) const
+{
+	auto handle_default = reinterpret_cast<FontFaceHandleDefault *>(handle);
+	return handle_default->GetLineHeight();
+}
+
+int FontEngineInterfaceDefault::GetBaseline(FontFaceHandle handle) const
+{
+	auto handle_default = reinterpret_cast<FontFaceHandleDefault *>(handle);
+	return handle_default->GetBaseline();
+}
+
+float FontEngineInterfaceDefault::GetUnderline(FontFaceHandle handle, float *thickness) const
+{
+	auto handle_default = reinterpret_cast<FontFaceHandleDefault *>(handle);
+	return handle_default->GetUnderline(thickness);
+}
+
+int FontEngineInterfaceDefault::GetStringWidth(FontFaceHandle handle, const String& string, CodePoint prior_character)
+{
+	auto handle_default = reinterpret_cast<FontFaceHandleDefault *>(handle);
+	return handle_default->GetStringWidth(string, prior_character);
+}
+
+int FontEngineInterfaceDefault::GenerateString(FontFaceHandle handle, GeometryList& geometry, const String& string,
+	const Vector2f& position, const Colourb& colour, int layer_configuration) const
+{
+	auto handle_default = reinterpret_cast<FontFaceHandleDefault *>(handle);
+	return handle_default->GenerateString(geometry, string, position, colour, layer_configuration);
+}
+
+#endif
+
+}
+}

+ 112 - 0
Source/Core/FontEngineInterfaceDefault.h

@@ -0,0 +1,112 @@
+/*
+ * This source file is part of RmlUi, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://github.com/mikke89/RmlUi
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#ifndef RMLUICOREFONTENGINEINTERFACEDEFAULT_H
+#define RMLUICOREFONTENGINEINTERFACEDEFAULT_H
+
+#include "../../Include/RmlUi/Core/FontEngineInterface.h"
+
+namespace Rml {
+namespace Core {
+
+class RMLUICORE_API FontEngineInterfaceDefault: public FontEngineInterface
+{
+public:
+	FontEngineInterfaceDefault();
+	virtual ~FontEngineInterfaceDefault();
+
+	/// Adds a new font face to the database. The face's family, style and weight will be determined from the face itself.
+	/// @param[in] file_name The file to load the face from.
+	/// @return True if the face was loaded successfully, false otherwise.
+	virtual bool LoadFontFace(const String& file_name) override;
+
+	/// Returns a handle to a font face that can be used to position and render text. This will return the closest match
+	/// it can find, but in the event a font family is requested that does not exist, NULL will be returned instead of a
+	/// valid handle.
+	/// @param[in] family The family of the desired font handle.
+	/// @param[in] charset The set of characters required in the font face, as a comma-separated list of unicode ranges.
+	/// @param[in] style The style of the desired font handle.
+	/// @param[in] weight The weight of the desired font handle.
+	/// @param[in] size The size of desired handle, in points.
+	/// @return A valid handle if a matching (or closely matching) font face was found, NULL otherwise.
+	virtual FontFaceHandle GetFontFaceHandle(const String& family, Style::FontStyle style, Style::FontWeight weight, int size) override;
+
+	/// Generates, if required, the layer configuration for a given array of font effects.
+    /// @param[in] FontHandle
+	/// @param[in] font_effects The list of font effects to generate the configuration for.
+	/// @return The index to use when generating geometry using this configuration.
+	virtual int GenerateLayerConfiguration(FontFaceHandle, const FontEffectList& font_effects) const override;
+
+	/// Returns the average advance of all glyphs in this font face.
+	/// @param[in] FontHandle
+	/// @return An approximate width of the characters in this font face.
+	virtual int GetCharacterWidth(FontFaceHandle) const override;
+
+	/// Returns the point size of this font face.
+	/// @param[in] FontHandle
+	/// @return The face's point size.
+	virtual int GetSize(FontFaceHandle) const override;
+	/// Returns the pixel height of a lower-case x in this font face.
+	/// @param[in] FontHandle
+	/// @return The height of a lower-case x.
+	virtual int GetXHeight(FontFaceHandle) const override;
+	/// Returns the default height between this font face's baselines.
+	/// @param[in] FontHandle
+	/// @return The default line height.
+	virtual int GetLineHeight(FontFaceHandle) const override;
+
+	/// Returns the font's baseline, as a pixel offset from the bottom of the font.
+	/// @param[in] FontHandle
+	/// @return The font's baseline.
+	virtual int GetBaseline(FontFaceHandle) const override;
+
+	/// Returns the font's underline, as a pixel offset from the bottom of the font.
+	/// @param[in] FontHandle
+	/// @return The font's underline thickness.
+	virtual float GetUnderline(FontFaceHandle, float *thickness) const override;
+
+	/// Returns the width a string will take up if rendered with this handle.
+	/// @param[in] FontHandle
+	/// @param[in] string The string to measure.
+	/// @param[in] prior_character The optionally-specified character that immediately precedes the string. This may have an impact on the string width due to kerning.
+	/// @return The width, in pixels, this string will occupy if rendered with this handle.
+	virtual int GetStringWidth(FontFaceHandle, const String& string, CodePoint prior_character) override;
+
+	/// Generates the geometry required to render a single line of text.
+	/// @param[out] geometry An array of geometries to generate the geometry into.
+	/// @param[in] FontHandle
+	/// @param[in] string The string to render.
+	/// @param[in] position The position of the baseline of the first character to render.
+	/// @param[in] colour The colour to render the text.
+	/// @return The width, in pixels, of the string geometry.
+	virtual int GenerateString(FontFaceHandle, GeometryList& geometry, const String& string, const Vector2f& position, const Colourb& colour, int layer_configuration) const override;
+};
+
+}
+}
+
+#endif

+ 2 - 2
Source/Core/FontFace.cpp

@@ -27,8 +27,8 @@
  */
 
 #include "precompiled.h"
-#include "../../Include/RmlUi/Core/FontFace.h"
-#include "FontFaceHandle.h"
+#include "FontFace.h"
+#include "FontFaceHandleDefault.h"
 #include "../../Include/RmlUi/Core/Log.h"
 
 namespace Rml {

+ 4 - 4
Include/RmlUi/Core/FontFace.h → Source/Core/FontFace.h

@@ -29,12 +29,12 @@
 #ifndef RMLUICOREFONTFACE_H
 #define RMLUICOREFONTFACE_H
 
-#include "ComputedValues.h"
+#include <RmlUi/Core/ComputedValues.h>
 
 namespace Rml {
 namespace Core {
 
-class FontFaceHandle;
+class FontFaceHandleDefault;
 
 /**
 	@author Peter Curry
@@ -56,7 +56,7 @@ public:
 	/// Returns a handle for positioning and rendering this face at the given size.
 	/// @param[in] size The size of the desired handle, in points.
 	/// @return The shared font handle.
-    virtual SharedPtr<FontFaceHandle> GetHandle(int size) = 0;
+    virtual SharedPtr<FontFaceHandleDefault> GetHandle(int size) = 0;
 
 	/// Releases the face's FreeType face structure. This will mean handles for new sizes cannot be constructed,
 	/// but existing ones can still be fetched.
@@ -69,7 +69,7 @@ protected:
 	bool release_stream;
 
 	// Key is font size
-	using HandleMap = UnorderedMap< int, SharedPtr<FontFaceHandle> >;
+	using HandleMap = UnorderedMap< int, SharedPtr<FontFaceHandleDefault> >;
 	HandleMap handles;
 };
 

+ 29 - 44
Source/Core/FontFaceHandle.cpp → Source/Core/FontFaceHandleDefault.cpp

@@ -27,7 +27,7 @@
  */
 
 #include "precompiled.h"
-#include "FontFaceHandle.h"
+#include "FontFaceHandleDefault.h"
 #include <algorithm>
 #include "../../Include/RmlUi/Core.h"
 #include "FontFaceLayer.h"
@@ -36,56 +36,66 @@
 namespace Rml {
 namespace Core {
 
-FontFaceHandle::FontFaceHandle()
+#ifndef RMLUI_NO_FONT_INTERFACE_DEFAULT
+	
+FontFaceHandleDefault::FontFaceHandleDefault()
 {
 	metrics = {};
 	base_layer = nullptr;
 }
 
-FontFaceHandle::~FontFaceHandle()
+FontFaceHandleDefault::~FontFaceHandleDefault()
 {
 	glyphs.clear();
 	layers.clear();
 }
 
 // Returns the point size of this font face.
-int FontFaceHandle::GetSize() const
+int FontFaceHandleDefault::GetSize() const
 {
 	return metrics.size;
 }
 
 // Returns the average advance of all glyphs in this font face.
-int FontFaceHandle::GetCharacterWidth() const
+int FontFaceHandleDefault::GetCharacterWidth() const
 {
 	return metrics.average_advance;
 }
 
 // Returns the pixel height of a lower-case x in this font face.
-int FontFaceHandle::GetXHeight() const
+int FontFaceHandleDefault::GetXHeight() const
 {
 	return metrics.x_height;
 }
 
 // Returns the default height between this font face's baselines.
-int FontFaceHandle::GetLineHeight() const
+int FontFaceHandleDefault::GetLineHeight() const
 {
 	return metrics.line_height;
 }
 
 // Returns the font's baseline.
-int FontFaceHandle::GetBaseline() const
+int FontFaceHandleDefault::GetBaseline() const
 {
 	return metrics.baseline;
 }
 
 // Returns the font's glyphs.
-const FontGlyphMap& FontFaceHandle::GetGlyphs() const
+const FontGlyphMap& FontFaceHandleDefault::GetGlyphs() const
 {
 	return glyphs;
 }
 
+float FontFaceHandleDefault::GetUnderline(float *thickness) const
+{
+	if (thickness != nullptr) {
+		*thickness = metrics.underline_thickness;
+	}
+	return metrics.underline_position;
+}
+
 // Returns the width a string will take up if rendered with this handle.
-int FontFaceHandle::GetStringWidth(const String& string, CodePoint prior_character) const
+int FontFaceHandleDefault::GetStringWidth(const String& string, CodePoint prior_character) const
 {
 	int width = 0;
 	for (auto it_string = StringIteratorU8(string); it_string; ++it_string)
@@ -116,7 +126,7 @@ int FontFaceHandle::GetStringWidth(const String& string, CodePoint prior_charact
 }
 
 // Generates, if required, the layer configuration for a given array of font effects.
-int FontFaceHandle::GenerateLayerConfiguration(const FontEffectList& font_effects)
+int FontFaceHandleDefault::GenerateLayerConfiguration(const FontEffectList& font_effects)
 {
 	if (font_effects.empty())
 		return 0;
@@ -179,7 +189,7 @@ int FontFaceHandle::GenerateLayerConfiguration(const FontEffectList& font_effect
 }
 
 // Generates the texture data for a layer (for the texture database).
-bool FontFaceHandle::GenerateLayerTexture(UniquePtr<const byte[]>& texture_data, Vector2i& texture_dimensions, FontEffect* layer_id, int texture_id)
+bool FontFaceHandleDefault::GenerateLayerTexture(UniquePtr<const byte[]>& texture_data, Vector2i& texture_dimensions, FontEffect* layer_id, int texture_id)
 {
 	FontLayerMap::iterator layer_iterator = layers.find(layer_id);
 	if (layer_iterator == layers.end())
@@ -189,7 +199,7 @@ bool FontFaceHandle::GenerateLayerTexture(UniquePtr<const byte[]>& texture_data,
 }
 
 // Generates the geometry required to render a single line of text.
-int FontFaceHandle::GenerateString(GeometryList& geometry, const String& string, const Vector2f& position, const Colourb& colour, int layer_configuration_index) const
+int FontFaceHandleDefault::GenerateString(GeometryList& geometry, const String& string, const Vector2f& position, const Colourb& colour, int layer_configuration_index) const
 {
 	int geometry_index = 0;
 	int line_width = 0;
@@ -259,42 +269,15 @@ int FontFaceHandle::GenerateString(GeometryList& geometry, const String& string,
 	return line_width;
 }
 
-// Generates the geometry required to render a line above, below or through a line of text.
-void FontFaceHandle::GenerateLine(Geometry* geometry, const Vector2f& position, int width, Style::TextDecoration height, const Colourb& colour) const
-{
-	std::vector< Vertex >& line_vertices = geometry->GetVertices();
-	std::vector< int >& line_indices = geometry->GetIndices();
-
-	float offset;
-	switch (height)
-	{
-	case Style::TextDecoration::Underline:       offset = -metrics.underline_position; break;
-	case Style::TextDecoration::Overline:        offset = -metrics.underline_position - (float)metrics.size; break;
-	case Style::TextDecoration::LineThrough:     offset = -0.65f * (float)metrics.x_height; break; // or maybe: -underline_position - (float)size * 0.5f
-	default: return;
-	}
-
-	line_vertices.resize(line_vertices.size() + 4);
-	line_indices.resize(line_indices.size() + 6);
-	GeometryUtilities::GenerateQuad(
-		&line_vertices[0] + ((int)line_vertices.size() - 4),
-		&line_indices[0] + ((int)line_indices.size() - 6),
-		Vector2f(position.x, position.y + offset).Round(),
-		Vector2f((float) width, metrics.underline_thickness),
-		colour, 
-		(int)line_vertices.size() - 4
-	);
-}
-
-FontGlyphMap& FontFaceHandle::GetGlyphs() {
+FontGlyphMap& FontFaceHandleDefault::GetGlyphs() {
 	return glyphs;
 }
 
-FontMetrics& FontFaceHandle::GetMetrics() {
+FontMetrics& FontFaceHandleDefault::GetMetrics() {
 	return metrics;
 }
 
-void FontFaceHandle::GenerateBaseLayer()
+void FontFaceHandleDefault::GenerateBaseLayer()
 {
 	base_layer = GenerateLayer(nullptr);
 	layer_configurations.push_back(LayerConfiguration());
@@ -302,7 +285,7 @@ void FontFaceHandle::GenerateBaseLayer()
 }
 
 // Generates (or shares) a layer derived from a font effect.
-FontFaceLayer* FontFaceHandle::GenerateLayer(const SharedPtr<const FontEffect>& font_effect)
+FontFaceLayer* FontFaceHandleDefault::GenerateLayer(const SharedPtr<const FontEffect>& font_effect)
 {
 	// See if this effect has been instanced before, as part of a different configuration.
 	FontLayerMap::iterator i = layers.find(font_effect.get());
@@ -348,5 +331,7 @@ FontFaceLayer* FontFaceHandle::GenerateLayer(const SharedPtr<const FontEffect>&
 	return layer;
 }
 
+#endif
+
 }
 }

+ 11 - 3
Source/Core/FontFaceHandle.h → Source/Core/FontFaceHandleDefault.h

@@ -38,6 +38,8 @@
 namespace Rml {
 namespace Core {
 
+#ifndef RMLUI_NO_FONT_INTERFACE_DEFAULT
+
 class FontFaceLayer;
 
 /**
@@ -57,11 +59,11 @@ struct FontMetrics {
 	float underline_thickness;
 };
 
-class FontFaceHandle : public NonCopyMoveable
+class FontFaceHandleDefault : public NonCopyMoveable
 {
 public:
-	FontFaceHandle();
-	virtual ~FontFaceHandle();
+	FontFaceHandleDefault();
+	virtual ~FontFaceHandleDefault();
 
 	/// Returns the average advance of all glyphs in this font face.
 	/// @return An approximate width of the characters in this font face.
@@ -81,6 +83,10 @@ public:
 	/// @return The font's baseline.
 	int GetBaseline() const;
 
+	/// Returns the font's underline, as a pixel offset from the bottom of the font.
+	/// @return The font's underline thickness.
+	float GetUnderline(float *thickness) const;
+
 	/// Returns the font's glyphs.
 	/// @return The font's glyphs.
 	const FontGlyphMap& GetGlyphs() const;
@@ -149,6 +155,8 @@ private:
 	FontMetrics metrics;
 };
 
+#endif
+
 }
 }
 

+ 6 - 2
Source/Core/FontFaceLayer.cpp

@@ -29,11 +29,13 @@
 #include "precompiled.h"
 #include "FontFaceLayer.h"
 #include "../../Include/RmlUi/Core/Core.h"
-#include "FontFaceHandle.h"
+#include "FontFaceHandleDefault.h"
 
 namespace Rml {
 namespace Core {
 
+#ifndef RMLUI_NO_FONT_INTERFACE_DEFAULT
+	
 FontFaceLayer::FontFaceLayer() : colour(255, 255, 255)
 {
 	handle = nullptr;
@@ -44,7 +46,7 @@ FontFaceLayer::~FontFaceLayer()
 }
 
 // Generates the character and texture data for the layer.
-bool FontFaceLayer::Initialise(const FontFaceHandle* _handle, SharedPtr<const FontEffect> _effect, const FontFaceLayer* clone, bool deep_clone)
+bool FontFaceLayer::Initialise(const FontFaceHandleDefault* _handle, SharedPtr<const FontEffect> _effect, const FontFaceLayer* clone, bool deep_clone)
 {
 	handle = _handle;
 	effect = _effect;
@@ -245,5 +247,7 @@ const Colourb& FontFaceLayer::GetColour() const
 	return colour;
 }
 
+#endif
+
 }
 }

+ 7 - 3
Source/Core/FontFaceLayer.h

@@ -38,8 +38,10 @@
 namespace Rml {
 namespace Core {
 
+#ifndef RMLUI_NO_FONT_INTERFACE_DEFAULT
+
 class FontEffect;
-class FontFaceHandle;
+class FontFaceHandleDefault;
 
 /**
 	A textured layer stored as part of a font face handle. Each handle will have at least a base
@@ -60,7 +62,7 @@ public:
 	/// @param[in] clone The layer to optionally clone geometry and texture data from.
 	/// @param[in] deep_clone If true, the clones geometry will be completely cloned and the effect will have no option to affect even the glyph origins.
 	/// @return True if the layer was generated successfully, false if not.
-	bool Initialise(const FontFaceHandle* handle, SharedPtr<const FontEffect> effect = {}, const FontFaceLayer* clone = nullptr, bool deep_clone = false);
+	bool Initialise(const FontFaceHandleDefault* handle, SharedPtr<const FontEffect> effect = {}, const FontFaceLayer* clone = nullptr, bool deep_clone = false);
 
 	/// Generates the texture data for a layer (for the texture database).
 	/// @param[out] texture_data The pointer to be set to the generated texture data.
@@ -137,7 +139,7 @@ private:
 	using CharacterMap = UnorderedMap<CodePoint, Character>;
 	using TextureList = std::vector<Texture>;
 
-	const FontFaceHandle* handle;
+	const FontFaceHandleDefault* handle;
 	SharedPtr<const FontEffect> effect;
 
 	TextureLayout texture_layout;
@@ -147,6 +149,8 @@ private:
 	Colourb colour;
 };
 
+#endif
+
 }
 }
 

+ 3 - 3
Source/Core/FontFamily.cpp

@@ -27,8 +27,8 @@
  */
 
 #include "precompiled.h"
-#include "../../Include/RmlUi/Core/FontFamily.h"
-#include "../../Include/RmlUi/Core/FontFace.h"
+#include "FontFamily.h"
+#include "FontFace.h"
 
 namespace Rml {
 namespace Core {
@@ -44,7 +44,7 @@ FontFamily::~FontFamily()
 }
 
 // Returns a handle to the most appropriate font in the family, at the correct size.
-SharedPtr<FontFaceHandle> FontFamily::GetFaceHandle(Style::FontStyle style, Style::FontWeight weight, int size)
+SharedPtr<FontFaceHandleDefault> FontFamily::GetFaceHandle(Style::FontStyle style, Style::FontWeight weight, int size)
 {
 	// Search for a face of the same style, and match the weight as closely as we can.
 	FontFace* matching_face = nullptr;

+ 3 - 3
Include/RmlUi/Core/FontFamily.h → Source/Core/FontFamily.h

@@ -29,13 +29,13 @@
 #ifndef RMLUICOREFONTFAMILY_H
 #define RMLUICOREFONTFAMILY_H
 
-#include "StringUtilities.h"
+#include <RmlUi/Core/StringUtilities.h>
 
 namespace Rml {
 namespace Core {
 
 class FontFace;
-class FontFaceHandle;
+class FontFaceHandleDefault;
 
 /**
 	@author Peter Curry
@@ -60,7 +60,7 @@ public:
 	/// @param[in] weight The weight of the desired handle.
 	/// @param[in] size The size of desired handle, in points.
 	/// @return A valid handle if a matching (or closely matching) font face was found, nullptr otherwise.
-	SharedPtr<FontFaceHandle> GetFaceHandle(Style::FontStyle style, Style::FontWeight weight, int size);
+	SharedPtr<FontFaceHandleDefault> GetFaceHandle(Style::FontStyle style, Style::FontWeight weight, int size);
 
 protected:
 	String name;

+ 17 - 4
Source/Core/FontProvider.cpp

@@ -27,22 +27,35 @@
  */
 
 #include "precompiled.h"
-#include <RmlUi/Core/FontProvider.h>
-#include <RmlUi/Core/FontFamily.h>
+#include "FontProvider.h"
+#include "FontFamily.h"
 
 namespace Rml {
 namespace Core {
 
+#ifndef RMLUI_NO_FONT_INTERFACE_DEFAULT
+
+const String FontProvider::debugger_font_family_name = "rmlui-debugger-font";
+
 // Returns a handle to a font face that can be used to position and render text.
-SharedPtr<FontFaceHandle> FontProvider::GetFontFaceHandle(const String& family, Style::FontStyle style, Style::FontWeight weight, int size)
+SharedPtr<FontFaceHandleDefault> FontProvider::GetFontFaceHandle(const String& family, Style::FontStyle style, Style::FontWeight weight, int size)
 {
 	RMLUI_ASSERTMSG(family == StringUtilities::ToLower(family), "Font family name must be converted to lowercase before entering here.");
-	FontFamilyMap::iterator iterator = font_families.find(family);
+
+	FontFamilyMap::iterator iterator;
+
+	if (family == debugger_font_family_name)
+		iterator = font_families.begin();
+	else
+		iterator = font_families.find(family);
+
 	if (iterator == font_families.end())
 		return nullptr;
 
 	return (*iterator).second->GetFaceHandle(style, weight, size);
 }
 
+#endif
+
 }
 }

+ 7 - 5
Include/RmlUi/Core/FontProvider.h → Source/Core/FontProvider.h

@@ -29,15 +29,15 @@
 #ifndef RMLUICOREFONTPROVIDER_H
 #define RMLUICOREFONTPROVIDER_H
 
-#include "Header.h"
-#include "StringUtilities.h"
-#include "ComputedValues.h"
+#include <RmlUi/Core/Header.h>
+#include <RmlUi/Core/StringUtilities.h>
+#include <RmlUi/Core/ComputedValues.h>
 
 namespace Rml {
 namespace Core {
 
-class FontFaceHandle;
 class FontFamily;
+class FontFaceHandleDefault;
 
 /**
     The font database contains all font families currently in use by RmlUi.
@@ -56,12 +56,14 @@ public:
     /// @param[in] weight The weight of the desired font handle.
     /// @param[in] size The size of desired handle, in points.
     /// @return A valid handle if a matching (or closely matching) font face was found, nullptr otherwise.
-	SharedPtr<FontFaceHandle> GetFontFaceHandle(const String& family, Style::FontStyle style, Style::FontWeight weight, int size);
+	SharedPtr<FontFaceHandleDefault> GetFontFaceHandle(const String& family, Style::FontStyle style, Style::FontWeight weight, int size);
 
 protected:
 
     typedef UnorderedMap< String, FontFamily*> FontFamilyMap;
     FontFamilyMap font_families;
+
+    static const String debugger_font_family_name;
 };
 
 }

+ 6 - 1
Source/Core/FreeType/FontFace.cpp

@@ -27,6 +27,9 @@
  */
 
 #include "precompiled.h"
+
+#ifndef RMLUI_NO_FONT_INTERFACE_DEFAULT
+
 #include "FontFace.h"
 #include "FontFaceHandle.h"
 #include "../../../Include/RmlUi/Core/Log.h"
@@ -45,7 +48,7 @@ FontFace_FreeType::~FontFace_FreeType()
 }
 
 // Returns a handle for positioning and rendering this face at the given size.
-SharedPtr<Rml::Core::FontFaceHandle> FontFace_FreeType::GetHandle(int size)
+SharedPtr<Rml::Core::FontFaceHandleDefault> FontFace_FreeType::GetHandle(int size)
 {
 	auto it = handles.find(size);
 	if (it != handles.end())
@@ -88,3 +91,5 @@ void FontFace_FreeType::ReleaseFace()
 
 }
 }
+
+#endif

+ 7 - 3
Source/Core/FreeType/FontFace.h

@@ -29,7 +29,9 @@
 #ifndef RMLUICOREFREETYPEFONTFACE_H
 #define RMLUICOREFREETYPEFONTFACE_H
 
-#include "../../../Include/RmlUi/Core/FontFace.h"
+#ifndef RMLUI_NO_FONT_INTERFACE_DEFAULT
+
+#include "../FontFace.h"
 #include <ft2build.h>
 #include FT_FREETYPE_H
 
@@ -40,7 +42,7 @@ namespace Core {
 	@author Peter Curry
  */
 
-class FontFaceHandle;
+class FontFaceHandleDefault;
 
 class FontFace_FreeType : public Rml::Core::FontFace
 {
@@ -51,7 +53,7 @@ public:
 	/// Returns a handle for positioning and rendering this face at the given size.
 	/// @param[in] size The size of the desired handle, in points.
 	/// @return The shared font handle.
-	SharedPtr<Rml::Core::FontFaceHandle> GetHandle(int size) override;
+	SharedPtr<Rml::Core::FontFaceHandleDefault> GetHandle(int size) override;
 
 	/// Releases the face's FreeType face structure. This will mean handles for new sizes cannot be constructed,
 	/// but existing ones can still be fetched.
@@ -65,3 +67,5 @@ private:
 }
 
 #endif
+
+#endif

+ 6 - 0
Source/Core/FreeType/FontFaceHandle.cpp

@@ -27,6 +27,9 @@
  */
 
 #include "precompiled.h"
+
+#ifndef RMLUI_NO_FONT_INTERFACE_DEFAULT
+
 #include "FontFaceHandle.h"
 #include <algorithm>
 #include "../../../Include/RmlUi/Core.h"
@@ -301,3 +304,6 @@ int FontFaceHandle_FreeType::GetKerning(CodePoint lhs, CodePoint rhs) const
 
 }
 }
+
+#endif
+

+ 6 - 2
Source/Core/FreeType/FontFaceHandle.h

@@ -29,7 +29,9 @@
 #ifndef RMLUICOREFREETYPEFONTFACEHANDLE_H
 #define RMLUICOREFREETYPEFONTFACEHANDLE_H
 
-#include "../FontFaceHandle.h"
+#ifndef RMLUI_NO_FONT_INTERFACE_DEFAULT
+
+#include "../FontFaceHandleDefault.h"
 #include "../../../Include/RmlUi/Core/FontEffect.h"
 #include "../../../Include/RmlUi/Core/FontGlyph.h"
 #include "../../../Include/RmlUi/Core/Geometry.h"
@@ -44,7 +46,7 @@ namespace Core {
 	@author Peter Curry
  */
 
-class FontFaceHandle_FreeType : public Rml::Core::FontFaceHandle
+class FontFaceHandle_FreeType : public Rml::Core::FontFaceHandleDefault
 {
 public:
 	FontFaceHandle_FreeType();
@@ -66,3 +68,5 @@ private:
 }
 
 #endif
+
+#endif

+ 5 - 0
Source/Core/FreeType/FontFamily.cpp

@@ -27,6 +27,9 @@
  */
 
 #include "precompiled.h"
+
+#ifndef RMLUI_NO_FONT_INTERFACE_DEFAULT
+
 #include "FontFamily.h"
 #include "FontFace.h"
 
@@ -54,3 +57,5 @@ bool FontFamily_FreeType::AddFace(void* ft_face, Style::FontStyle style, Style::
 
 }
 }
+
+#endif

+ 5 - 1
Source/Core/FreeType/FontFamily.h

@@ -29,7 +29,9 @@
 #ifndef RMLUICOREFREETYPEFONTFAMILY_H
 #define RMLUICOREFREETYPEFONTFAMILY_H
 
-#include <RmlUi/Core/FontFamily.h>
+#ifndef RMLUI_NO_FONT_INTERFACE_DEFAULT
+
+#include "../FontFamily.h"
 #include <ft2build.h>
 #include FT_FREETYPE_H
 
@@ -59,3 +61,5 @@ public:
 }
 
 #endif
+
+#endif

+ 9 - 73
Source/Core/FreeType/FontProvider.cpp

@@ -27,9 +27,12 @@
  */
 
 #include "precompiled.h"
-#include <RmlUi/Core/FreeType/FontProvider.h>
+
+#ifndef RMLUI_NO_FONT_INTERFACE_DEFAULT
+
+#include "FontProvider.h"
 #include "FontFaceHandle.h"
-#include <RmlUi/Core/FontDatabase.h>
+#include "../FontDatabaseDefault.h"
 #include "FontFamily.h"
 #include <RmlUi/Core.h>
 #include <ft2build.h>
@@ -60,7 +63,7 @@ bool FontProvider_FreeType::Initialise()
 	{
 		new FontProvider_FreeType();
 
-		FontDatabase::AddFontProvider(instance);
+		FontDatabaseDefault::AddFontProvider(instance);
 
 		FT_Error result = FT_Init_FreeType(&ft_library);
 		if (result != 0)
@@ -87,7 +90,7 @@ void FontProvider_FreeType::Shutdown()
 			ft_library = nullptr;
 		}
 
-		FontDatabase::RemoveFontProvider(instance);
+		FontDatabaseDefault::RemoveFontProvider(instance);
 		delete instance;
 		instance = nullptr;
 	}
@@ -118,75 +121,6 @@ bool FontProvider_FreeType::LoadFontFace(const String& file_name)
 	}
 }
 
-// Adds a new font face to the database, ignoring any family, style and weight information stored in the face itself.
-bool FontProvider_FreeType::LoadFontFace(const String& file_name, const String& family, Style::FontStyle style, Style::FontWeight weight)
-{
-	FT_Face ft_face = (FT_Face) instance->LoadFace(file_name);
-	if (ft_face == nullptr)
-	{
-		Log::Message(Log::LT_ERROR, "Failed to load font face from %s.", file_name.c_str());
-		return false;
-	}
-
-	if (instance->AddFace(ft_face, family, style, weight, true))
-	{
-		Log::Message(Log::LT_INFO, "Loaded font face %s %s (from %s).", ft_face->family_name, ft_face->style_name, file_name.c_str());
-		return true;
-	}
-	else
-	{
-		Log::Message(Log::LT_ERROR, "Failed to load font face %s %s (from %s).", ft_face->family_name, ft_face->style_name, file_name.c_str());
-		return false;
-	}
-}
-
-// Adds a new font face to the database, loading from memory.
-bool FontProvider_FreeType::LoadFontFace(const byte* data, int data_length)
-{
-	FT_Face ft_face = (FT_Face) instance->LoadFace(data, data_length, "memory", false);
-	if (ft_face == nullptr)
-	{
-		Log::Message(Log::LT_ERROR, "Failed to load font face from byte stream.");
-		return false;
-	}
-
-	Style::FontStyle style = ft_face->style_flags & FT_STYLE_FLAG_ITALIC ? Style::FontStyle::Italic : Style::FontStyle::Normal;
-	Style::FontWeight weight = ft_face->style_flags & FT_STYLE_FLAG_BOLD ? Style::FontWeight::Bold : Style::FontWeight::Normal;
-
-	if (instance->AddFace(ft_face, ft_face->family_name, style, weight, false))
-	{
-		Log::Message(Log::LT_INFO, "Loaded font face %s %s (from byte stream).", ft_face->family_name, ft_face->style_name);
-		return true;
-	}
-	else
-	{
-		Log::Message(Log::LT_ERROR, "Failed to load font face %s %s (from byte stream).", ft_face->family_name, ft_face->style_name);
-		return false;
-	}
-}
-
-// Adds a new font face to the database, loading from memory, ignoring any family, style and weight information stored in the face itself.
-bool FontProvider_FreeType::LoadFontFace(const byte* data, int data_length, const String& family, Style::FontStyle style, Style::FontWeight weight)
-{
-	FT_Face ft_face = (FT_Face) instance->LoadFace(data, data_length, "memory", false);
-	if (ft_face == nullptr)
-	{
-		Log::Message(Log::LT_ERROR, "Failed to load font face from byte stream.");
-		return false;
-	}
-
-	if (instance->AddFace(ft_face, family, style, weight, false))
-	{
-		Log::Message(Log::LT_INFO, "Loaded font face %s %s (from byte stream).", ft_face->family_name, ft_face->style_name);
-		return true;
-	}
-	else
-	{
-		Log::Message(Log::LT_ERROR, "Failed to load font face %s %s (from byte stream).", ft_face->family_name, ft_face->style_name);
-		return false;
-	}
-}
-
 // Adds a loaded face to the appropriate font family.
 bool FontProvider_FreeType::AddFace(void* face, const String& family, Style::FontStyle style, Style::FontWeight weight, bool release_stream)
 {
@@ -258,3 +192,5 @@ void* FontProvider_FreeType::LoadFace(const byte* data, int data_length, const S
 
 }
 }
+
+#endif

+ 5 - 21
Include/RmlUi/Core/FreeType/FontProvider.h → Source/Core/FreeType/FontProvider.h

@@ -29,7 +29,9 @@
 #ifndef RMLUICOREFREETYPEFONTPROVIDER_H
 #define RMLUICOREFREETYPEFONTPROVIDER_H
 
-#include "../StringUtilities.h"
+#ifndef RMLUI_NO_FONT_INTERFACE_DEFAULT
+
+#include <RmlUi/Core/StringUtilities.h>
 #include "../FontProvider.h"
 
 namespace Rml {
@@ -50,26 +52,6 @@ public:
     /// @param[in] file_name The file to load the face from.
     /// @return True if the face was loaded successfully, false otherwise.
     static bool LoadFontFace(const String& file_name);
-    /// Adds a new font face to the database, ignoring any family, style and weight information stored in the face itself.
-    /// @param[in] file_name The file to load the face from.
-    /// @param[in] family The family to add the face to.
-    /// @param[in] style The style of the face (normal or italic).
-    /// @param[in] weight The weight of the face (normal or bold).
-    /// @return True if the face was loaded successfully, false otherwise.
-    static bool LoadFontFace(const String& file_name, const String& family, Style::FontStyle style, Style::FontWeight weight);
-    /// Adds a new font face to the database, loading from memory. The face's family, style and weight will be determined from the face itself.
-    /// @param[in] data The font data.
-    /// @param[in] data_length Length of the data.
-    /// @return True if the face was loaded successfully, false otherwise.
-    static bool LoadFontFace(const byte* data, int data_length);
-    /// Adds a new font face to the database, loading from memory.
-    /// @param[in] data The font data.
-    /// @param[in] data_length Length of the data.
-    /// @param[in] family The family to add the face to.
-    /// @param[in] style The style of the face (normal or italic).
-    /// @param[in] weight The weight of the face (normal or bold).
-    /// @return True if the face was loaded successfully, false otherwise.
-    static bool LoadFontFace(const byte* data, int data_length, const String& family, Style::FontStyle style, Style::FontWeight weight);
 
 private:
     FontProvider_FreeType(void);
@@ -89,3 +71,5 @@ private:
 }
 
 #endif
+
+#endif

+ 4 - 0
Source/Core/FreeType/precompiled.h

@@ -29,6 +29,10 @@
 #ifndef RMLUICOREFREETYPEFONTPRECOMPILED_H
 #define RMLUICOREFREETYPEFONTPRECOMPILED_H
 
+#ifndef RMLUI_NO_FONT_INTERFACE_DEFAULT
+
 #include "../precompiled.h"
 
 #endif
+
+#endif

+ 31 - 0
Source/Core/GeometryUtilities.cpp

@@ -74,5 +74,36 @@ void GeometryUtilities::GenerateQuad(Vertex* vertices, int* indices, const Vecto
 	indices[5] = index_offset + 2;
 }
 
+// Generates the geometry required to render a line above, below or through a line of text.
+void GeometryUtilities::GenerateLine(FontFaceHandle font_face_handle, Geometry* geometry, const Vector2f& position, int width, Style::TextDecoration height, const Colourb& colour)
+{
+	std::vector< Vertex >& line_vertices = geometry->GetVertices();
+	std::vector< int >& line_indices = geometry->GetIndices();
+	float underline_thickness = 0;
+	float underline_position = GetFontEngineInterface()->GetUnderline(font_face_handle, &underline_thickness);
+	int size = GetFontEngineInterface()->GetSize(font_face_handle);
+	int x_height = GetFontEngineInterface()->GetXHeight(font_face_handle);
+
+	float offset;
+	switch (height)
+	{
+		case Style::TextDecoration::Underline:       offset = -underline_position; break;
+		case Style::TextDecoration::Overline:        offset = -underline_position - (float)size; break;
+		case Style::TextDecoration::LineThrough:     offset = -0.65f * (float)x_height; break; // or maybe: -underline_position - (float)size * 0.5f
+		default: return;
+	}
+
+	line_vertices.resize(line_vertices.size() + 4);
+	line_indices.resize(line_indices.size() + 6);
+	GeometryUtilities::GenerateQuad(
+									&line_vertices[0] + ((int)line_vertices.size() - 4),
+									&line_indices[0] + ((int)line_indices.size() - 6),
+									Vector2f(position.x, position.y + offset).Round(),
+									Vector2f((float) width, underline_thickness),
+									colour,
+									(int)line_vertices.size() - 4
+									);
+}
+
 }
 }

+ 20 - 20
Source/Core/LayoutInlineBox.cpp

@@ -28,7 +28,7 @@
 
 #include "precompiled.h"
 #include "LayoutInlineBox.h"
-#include "FontFaceHandle.h"
+#include "FontFaceHandleDefault.h"
 #include "LayoutBlockBox.h"
 #include "LayoutEngine.h"
 #include "../../Include/RmlUi/Core/ElementText.h"
@@ -57,11 +57,11 @@ LayoutInlineBox::LayoutInlineBox(Element* _element, const Box& _box) : position(
 	}
 	else
 	{
-		FontFaceHandle* font_face = element->GetFontFaceHandle();
-		if (font_face != nullptr)
+		FontFaceHandle font_face = element->GetFontFaceHandle();
+		if (font_face != 0)
 		{
 			height = element->GetLineHeight();
-			baseline = (height - font_face->GetLineHeight()) * 0.5f + font_face->GetBaseline();
+			baseline = (height - GetFontEngineInterface()->GetLineHeight(font_face)) * 0.5f + GetFontEngineInterface()->GetBaseline(font_face);
 		}
 		else
 		{
@@ -179,10 +179,10 @@ void LayoutInlineBox::CalculateBaseline(float& ascender, float& descender)
 		// The middle of this box is aligned with the baseline of its parent's plus half an ex.
 		case VerticalAlign::Middle:
 		{
-			FontFaceHandle* parent_font = GetParentFont();
+			FontFaceHandle parent_font = GetParentFont();
 			int x_height = 0;
-			if (parent_font != nullptr)
-				x_height = parent_font->GetXHeight() / -2;
+			if (parent_font != 0)
+				x_height = GetFontEngineInterface()->GetXHeight(parent_font) / -2;
 
 			SetVerticalPosition(x_height + (height / 2 - baseline));
 		}
@@ -191,44 +191,44 @@ void LayoutInlineBox::CalculateBaseline(float& ascender, float& descender)
 		// This box's baseline is offset from its parent's so it is appropriate for rendering subscript.
 		case VerticalAlign::Sub:
 		{
-			FontFaceHandle* parent_font = GetParentFont();
-			if (parent_font == nullptr)
+			FontFaceHandle parent_font = GetParentFont();
+			if (parent_font == 0)
 				SetVerticalPosition(0);
 			else
-				SetVerticalPosition(float(parent_font->GetLineHeight()) * 0.2f);
+				SetVerticalPosition(float(GetFontEngineInterface()->GetLineHeight(parent_font)) * 0.2f);
 		}
 		break;
 
 		// This box's baseline is offset from its parent's so it is appropriate for rendering superscript.
 		case VerticalAlign::Super:
 		{
-			FontFaceHandle* parent_font = GetParentFont();
-			if (parent_font == nullptr)
+			FontFaceHandle parent_font = GetParentFont();
+			if (parent_font == 0)
 				SetVerticalPosition(0);
 			else
-				SetVerticalPosition(float(-1 * parent_font->GetLineHeight()) * 0.4f);
+				SetVerticalPosition(float(-1 * GetFontEngineInterface()->GetLineHeight(parent_font)) * 0.4f);
 		}
 		break;
 
 		// The top of this box is aligned to the top of its parent's font.
 		case VerticalAlign::TextTop:
 		{
-			FontFaceHandle* parent_font = GetParentFont();
-			if (parent_font == nullptr)
+			FontFaceHandle parent_font = GetParentFont();
+			if (parent_font == 0)
 				SetVerticalPosition(0);
 			else
-				SetVerticalPosition((height - baseline) - (parent_font->GetLineHeight() - parent_font->GetBaseline()));
+				SetVerticalPosition((height - baseline) - (GetFontEngineInterface()->GetLineHeight(parent_font) - GetFontEngineInterface()->GetBaseline(parent_font)));
 		}
 		break;
 
 		// The bottom of this box is aligned to the bottom of its parent's font (not the baseline).
 		case VerticalAlign::TextBottom:
 		{
-			FontFaceHandle* parent_font = GetParentFont();
-			if (parent_font == nullptr)
+			FontFaceHandle parent_font = GetParentFont();
+			if (parent_font == 0)
 				SetVerticalPosition(0);
 			else
-				SetVerticalPosition(parent_font->GetBaseline() - baseline);
+				SetVerticalPosition(GetFontEngineInterface()->GetBaseline(parent_font) - baseline);
 		}
 		break;
 
@@ -407,7 +407,7 @@ void LayoutInlineBox::operator delete(void* chunk)
 }
 
 // Returns our parent box's font face handle.
-FontFaceHandle* LayoutInlineBox::GetParentFont() const
+FontFaceHandle LayoutInlineBox::GetParentFont() const
 {
 	if (parent == nullptr)
 		return line->GetBlockBox()->GetParent()->GetElement()->GetFontFaceHandle();

+ 2 - 2
Source/Core/LayoutInlineBox.h

@@ -36,7 +36,7 @@ namespace Core {
 
 class Element;
 class ElementText;
-class FontFaceHandle;
+class FontFaceHandleDefault;
 class LayoutBlockBox;
 class LayoutLineBox;
 
@@ -138,7 +138,7 @@ public:
 protected:
 	/// Returns our parent box's font face handle.
 	/// @return The font face handle of our parent box.
-	FontFaceHandle* GetParentFont() const;
+	FontFaceHandle GetParentFont() const;
 
 	// The box's element.
 	Element* element;

+ 6 - 6
Source/Core/LayoutInlineBoxText.cpp

@@ -28,7 +28,7 @@
 
 #include "precompiled.h"
 #include "LayoutInlineBoxText.h"
-#include "FontFaceHandle.h"
+#include "FontFaceHandleDefault.h"
 #include "LayoutEngine.h"
 #include "LayoutLineBox.h"
 #include "../../Include/RmlUi/Core/ElementText.h"
@@ -97,9 +97,9 @@ void LayoutInlineBoxText::OffsetBaseline(float ascender)
 	// Calculate the leading (the difference between font height and line height).
 	float leading = 0;
 
-	FontFaceHandle* font_face_handle = element->GetFontFaceHandle();
-	if (font_face_handle != nullptr)
-		leading = height - font_face_handle->GetLineHeight();
+	FontFaceHandle font_face_handle = element->GetFontFaceHandle();
+	if (font_face_handle != 0)
+		leading = height - GetFontEngineInterface()->GetLineHeight(font_face_handle);
 
 	// Offset by the half-leading.
 	position.y += leading * 0.5f;
@@ -151,8 +151,8 @@ void LayoutInlineBoxText::BuildWordBox()
 	ElementText* text_element = GetTextElement();
 	RMLUI_ASSERT(text_element != nullptr);
 
-	FontFaceHandle* font_face_handle = text_element->GetFontFaceHandle();
-	if (font_face_handle == nullptr)
+	FontFaceHandle font_face_handle = text_element->GetFontFaceHandle();
+	if (font_face_handle == 0)
 	{
 		height = 0;
 		baseline = 0;

+ 1 - 1
Source/Core/LayoutLineBox.cpp

@@ -31,7 +31,7 @@
 #include "LayoutBlockBox.h"
 #include "LayoutEngine.h"
 #include "LayoutInlineBoxText.h"
-#include "FontFaceHandle.h"
+#include "FontFaceHandleDefault.h"
 #include "../../Include/RmlUi/Core/Property.h"
 #include "../../Include/RmlUi/Core/ElementUtilities.h"
 #include "../../Include/RmlUi/Core/ElementText.h"

+ 1 - 1
Source/Core/Lua/RmlUi.cpp

@@ -75,7 +75,7 @@ int LuaRmlUiCreateContext(lua_State* L, LuaRmlUi* obj)
 int LuaRmlUiLoadFontFace(lua_State* L, LuaRmlUi* obj)
 {
     const char* file = luaL_checkstring(L,1);
-    lua_pushboolean(L,FontDatabase::LoadFontFace(file));
+    lua_pushboolean(L,GetFontEngineInterface()->LoadFontFace(file));
     return 1;
 }
 

+ 5 - 2
Source/Core/TextureResource.cpp

@@ -28,7 +28,7 @@
 
 #include "precompiled.h"
 #include "TextureResource.h"
-#include "FontFaceHandle.h"
+#include "FontFaceHandleDefault.h"
 #include "TextureDatabase.h"
 #include "../../Include/RmlUi/Core.h"
 
@@ -127,10 +127,12 @@ bool TextureResource::Load(RenderInterface* render_interface)
 
 		// Find the generation protocol and generate the data accordingly.
 		String protocol = source.substr(1, source.find("::") - 1);
+
+#ifndef RMLUI_NO_FONT_INTERFACE_DEFAULT
 		if (protocol == "font")
 		{
 			// The requested texture is a font layer.
-			FontFaceHandle* handle;
+			FontFaceHandleDefault* handle;
 			FontEffect* layer_id;
 			int texture_id;
 			
@@ -142,6 +144,7 @@ bool TextureResource::Load(RenderInterface* render_interface)
 											 texture_id);
 			}
 		}
+#endif
 
 		// If texture data was generated, great! Otherwise, fallback to the LoadTexture() code and
 		// hope the client knows what the hell to do with the question mark in their file name.

+ 1 - 1
Source/Debugger/BeaconSource.h

@@ -34,7 +34,7 @@ body
 	right: 33dp;
 	z-index: 1000000;
 	width: 20px;
-	font-family: Lacuna;
+	font-family: rmlui-debugger-font;
 	font-size: 12dp;
 	color: black;
 	visibility: hidden;

+ 1 - 1
Source/Debugger/CommonSource.h

@@ -29,7 +29,7 @@
 static const char* common_rcss = R"RCSS(
 body
 {
-	font-family: Lacuna;
+	font-family: rmlui-debugger-font;
 	z-index: 1000000;
 	font-size: 13dp;
 	line-height: 1.4;

+ 1 - 1
Source/Debugger/MenuSource.h

@@ -34,7 +34,7 @@ body
 	position: absolute;
 	z-index: 1000000;
 	background: #888;
-	font-family: Lacuna;
+	font-family: rmlui-debugger-font;
 	font-size: 14dp;
 	color: black;
 }

+ 0 - 12
Source/Debugger/Plugin.cpp

@@ -72,12 +72,6 @@ bool Plugin::Initialise(Core::Context* context)
 	host_context = context;
 	Geometry::SetContext(context);
 
-	if (!LoadFont())
-	{
-		Core::Log::Message(Core::Log::LT_ERROR, "Failed to initialise debugger, unable to load font.");
-		return false;
-	}
-
 	if (!LoadMenuElement() ||
 		!LoadInfoElement() ||
 		!LoadLogElement())
@@ -275,12 +269,6 @@ Plugin* Plugin::GetInstance()
 	return instance;
 }
 
-bool Plugin::LoadFont()
-{
-	return (Core::FontDatabase::LoadFontFace(lacuna_regular, sizeof(lacuna_regular) / sizeof(unsigned char), "Lacuna", Core::Style::FontStyle::Normal, Core::Style::FontWeight::Normal) &&
-			Core::FontDatabase::LoadFontFace(lacuna_italic, sizeof(lacuna_italic) / sizeof(unsigned char), "Lacuna", Core::Style::FontStyle::Italic, Core::Style::FontWeight::Normal));
-}
-
 bool Plugin::LoadMenuElement()
 {
 	menu_element = host_context->CreateDocument();

+ 0 - 1
Source/Debugger/Plugin.h

@@ -100,7 +100,6 @@ public:
 	static Plugin* GetInstance();
 
 private:
-	bool LoadFont();
 	bool LoadMenuElement();
 	bool LoadInfoElement();
 	bool LoadLogElement();