Browse Source

Merge pull request #1 from libRocket/master

Merge from main repo
Denis A. Kerzhemanov 10 years ago
parent
commit
7293db02d8
85 changed files with 4466 additions and 655 deletions
  1. 122 54
      Build/CMakeLists.txt
  2. 25 2
      Build/cmake/FileList.cmake
  3. 165 0
      Build/cmake/FindSDL2.cmake
  4. 119 0
      Build/cmake/FindSDL2_image.cmake
  5. 4 7
      Build/cmake/Platform/iOS.cmake
  6. 7 0
      Build/cmake/SampleFileList.cmake
  7. 11 0
      Build/libRocketConfig.cmake.build.in
  8. 7 0
      Build/libRocketConfig.cmake.install.in
  9. 120 0
      Dependencies/osx-depends.sh
  10. 6 1
      Include/Rocket/Controls/Header.h
  11. 6 1
      Include/Rocket/Controls/Lua/Header.h
  12. 101 0
      Include/Rocket/Core/BitmapFont/FontProvider.h
  13. 2 0
      Include/Rocket/Core/Element.h
  14. 17 10
      Include/Rocket/Core/FontDatabase.h
  15. 6 9
      Include/Rocket/Core/FontFace.h
  16. 6 7
      Include/Rocket/Core/FontFamily.h
  17. 70 0
      Include/Rocket/Core/FontProvider.h
  18. 101 0
      Include/Rocket/Core/FreeType/FontProvider.h
  19. 6 1
      Include/Rocket/Core/Header.h
  20. 6 1
      Include/Rocket/Core/Lua/Header.h
  21. 1 1
      Include/Rocket/Core/Platform.h
  22. 6 1
      Include/Rocket/Core/Python/Header.h
  23. 6 1
      Include/Rocket/Debugger/Header.h
  24. 270 0
      Samples/assets/Arial.fnt
  25. BIN
      Samples/assets/Arial_0.tga
  26. 28 0
      Samples/assets/bitmapfont.rml
  27. 130 0
      Samples/basic/bitmapfont/src/main.cpp
  28. 12 0
      Samples/basic/sdl2/src/main.cpp
  29. 1 1
      Samples/luainvaders/src/LuaInterface.cpp
  30. 1 0
      Samples/pyinvaders/src/main.cpp
  31. 3 1
      Samples/shell/src/macosx/ShellRenderInterfaceExtensionsOpenGL_MacOSX.cpp
  32. 1 1
      Source/Controls/ElementDataGridRow.cpp
  33. 6 6
      Source/Controls/Lua/DataSource.cpp
  34. 5 5
      Source/Controls/Lua/ElementFormControlInput.cpp
  35. 3 3
      Source/Controls/Lua/ElementFormControlSelect.cpp
  36. 3 3
      Source/Controls/Lua/ElementFormControlTextArea.cpp
  37. 3 3
      Source/Controls/Lua/ElementTabSet.cpp
  38. 1 1
      Source/Controls/Lua/LuaDataSource.cpp
  39. 1 1
      Source/Controls/Lua/SelectOptionsProxy.cpp
  40. 147 0
      Source/Core/BitmapFont/BitmapFontDefinitions.h
  41. 130 0
      Source/Core/BitmapFont/FontFace.cpp
  42. 68 0
      Source/Core/BitmapFont/FontFace.h
  43. 428 0
      Source/Core/BitmapFont/FontFaceHandle.cpp
  44. 136 0
      Source/Core/BitmapFont/FontFaceHandle.h
  45. 127 0
      Source/Core/BitmapFont/FontFaceLayer.cpp
  46. 78 0
      Source/Core/BitmapFont/FontFaceLayer.h
  47. 55 0
      Source/Core/BitmapFont/FontFamily.cpp
  48. 66 0
      Source/Core/BitmapFont/FontFamily.h
  49. 112 0
      Source/Core/BitmapFont/FontParser.cpp
  50. 68 0
      Source/Core/BitmapFont/FontParser.h
  51. 208 0
      Source/Core/BitmapFont/FontProvider.cpp
  52. 6 1
      Source/Core/DecoratorTiled.cpp
  53. 7 2
      Source/Core/Element.cpp
  54. 1 0
      Source/Core/ElementDocument.cpp
  55. 5 0
      Source/Core/ElementStyle.cpp
  56. 2 0
      Source/Core/ElementStyle.h
  57. 38 0
      Source/Core/ElementStyleCache.cpp
  58. 4 0
      Source/Core/ElementStyleCache.h
  59. 94 158
      Source/Core/FontDatabase.cpp
  60. 2 95
      Source/Core/FontFace.cpp
  61. 0 209
      Source/Core/FontFaceHandle.cpp
  62. 7 26
      Source/Core/FontFaceHandle.h
  63. 3 3
      Source/Core/FontFaceLayer.h
  64. 2 11
      Source/Core/FontFamily.cpp
  65. 45 0
      Source/Core/FontProvider.cpp
  66. 139 0
      Source/Core/FreeType/FontFace.cpp
  67. 68 0
      Source/Core/FreeType/FontFace.h
  68. 458 0
      Source/Core/FreeType/FontFaceHandle.cpp
  69. 117 0
      Source/Core/FreeType/FontFaceHandle.h
  70. 58 0
      Source/Core/FreeType/FontFamily.cpp
  71. 67 0
      Source/Core/FreeType/FontFamily.h
  72. 258 0
      Source/Core/FreeType/FontProvider.cpp
  73. 45 5
      Source/Core/LayoutEngine.cpp
  74. 8 8
      Source/Core/Lua/Colourb.cpp
  75. 1 1
      Source/Core/Lua/ContextDocumentsProxy.cpp
  76. 1 1
      Source/Core/Lua/Element.cpp
  77. 1 1
      Source/Core/Lua/ElementChildNodesProxy.cpp
  78. 1 1
      Source/Core/Lua/GlobalLuaFunctions.cpp
  79. 1 1
      Source/Core/Lua/RocketContextsProxy.cpp
  80. 6 6
      Source/Core/Lua/Vector2i.cpp
  81. 1 0
      Source/Core/StringCache.cpp
  82. 1 0
      Source/Core/StringCache.h
  83. 4 1
      Source/Core/TextureLayoutTexture.cpp
  84. 2 2
      Source/Debugger/Plugin.cpp
  85. 2 2
      how_to_build_for_mingw.txt

+ 122 - 54
Build/CMakeLists.txt

@@ -2,12 +2,31 @@
 # Build script for libRocket =======
 # Build script for libRocket =======
 #===================================
 #===================================
 
 
-# This has to be before most other options so CMake properly handles the 
-# compiler variables, it MUST bebefore the project() definition
 if(APPLE)
 if(APPLE)
+	# This has to be before most other options so CMake properly handles the 
+	# compiler variables, it MUST bebefore the project() definition
 	if(IOS_PLATFORM)
 	if(IOS_PLATFORM)
 		set(CMAKE_TOOLCHAIN_FILE cmake/Platform/iOS.cmake)
 		set(CMAKE_TOOLCHAIN_FILE cmake/Platform/iOS.cmake)
 	endif(IOS_PLATFORM)
 	endif(IOS_PLATFORM)
+
+	option(BUILD_UNIVERSAL_BINARIES "Build universal binaries for all architectures supported" ON)
+	if (NOT CMAKE_OSX_ARCHITECTURES AND BUILD_UNIVERSAL_BINARIES)
+		if(IOS)
+			# set the architecture for iOS 
+			if (${IOS_PLATFORM} STREQUAL "OS")
+				set (IOS_ARCH armv6 armv7 armv7s arm64)
+				set (CMAKE_OSX_ARCHITECTURES ${IOS_ARCH} CACHE string  "Build architecture for iOS")
+			else (${IOS_PLATFORM} STREQUAL "OS")
+				set (IOS_ARCH i386 x86_64)
+				set (CMAKE_OSX_ARCHITECTURES ${IOS_ARCH} CACHE string  "Build architecture for iOS Simulator")
+			endif (${IOS_PLATFORM} STREQUAL "OS")
+
+		else(IOS)
+			# set the architectures for OS X
+			set (OSXI_ARCH i386 x86_64)
+			set (CMAKE_OSX_ARCHITECTURES ${OSXI_ARCH} CACHE string  "Build architecture for OS X universal binaries")		
+		endif(IOS)
+	endif (NOT CMAKE_OSX_ARCHITECTURES AND BUILD_UNIVERSAL_BINARIES)
 endif(APPLE)
 endif(APPLE)
 
 
 # We use the new OSX_ARCHITECTURES property
 # We use the new OSX_ARCHITECTURES property
@@ -18,6 +37,18 @@ if(COMMAND cmake_policy)
   cmake_policy(SET CMP0015 NEW)
   cmake_policy(SET CMP0015 NEW)
 endif(COMMAND cmake_policy)
 endif(COMMAND cmake_policy)
 
 
+# Enable the use of MACOSX_RPATH by default for CMake v3.0+; this effectively 
+# allows plug 'n' play functionality, so to speak -- the resulting shared 
+# library files can simply be copied over into the end-user's application 
+# bundle or framework bundle. No mucking around with install_name_tool.
+#
+# 	See also: 
+# cmake --help-policy cmp0042
+# http://www.kitware.com/blog/home/post/510
+if(POLICY CMP0042)
+  cmake_policy(SET CMP0042 NEW)
+endif(POLICY CMP0042)
+
 project(libRocket C CXX)
 project(libRocket C CXX)
 
 
 # paths
 # paths
@@ -55,20 +86,23 @@ if(NOT DEFINED ENV{FREETYPE_DIR})
 	set(ENV{FREETYPE_DIR} "${PROJECT_SOURCE_DIR}/../Dependencies")
 	set(ENV{FREETYPE_DIR} "${PROJECT_SOURCE_DIR}/../Dependencies")
 endif()
 endif()
 
 
-if(NOT DEFINED ENV{Boost_DIR})
-	set(ENV{Boost_DIR} "${PROJECT_SOURCE_DIR}/../Dependencies")
+#if(NOT DEFINED ENV{Boost_DIR})
+#	set(ENV{Boost_DIR} "${PROJECT_SOURCE_DIR}/../Dependencies")
+#endif()
+if(NOT DEFINED ENV{BOOST_ROOT})
+	set(ENV{BOOST_ROOT} "${PROJECT_SOURCE_DIR}/../Dependencies/boost")
 endif()
 endif()
 
 
 if(NOT DEFINED ENV{LUA_DIR})
 if(NOT DEFINED ENV{LUA_DIR})
 	set(ENV{LUA_DIR} "${PROJECT_SOURCE_DIR}/../Dependencies")
 	set(ENV{LUA_DIR} "${PROJECT_SOURCE_DIR}/../Dependencies")
 endif()
 endif()
 
 
-if(NOT DEFINED ENV{SDLDIR})
-	set(ENV{SDLDIR} "${PROJECT_SOURCE_DIR}/../Dependencies")
+if(NOT DEFINED ENV{SDL2DIR})
+	set(ENV{SDL2DIR} "${PROJECT_SOURCE_DIR}/../Dependencies")
 endif()
 endif()
 
 
-if(NOT DEFINED ENV{SDLIMAGEDIR})
-	set(ENV{SDLIMAGEDIR} "${PROJECT_SOURCE_DIR}/../Dependencies")
+if(NOT DEFINED ENV{SDL2_IMAGE_DIR})
+	set(ENV{SDL2_IMAGE_DIR} "${PROJECT_SOURCE_DIR}/../Dependencies")
 endif()
 endif()
 
 
 if(NOT DEFINED ENV{SFML_ROOT})
 if(NOT DEFINED ENV{SFML_ROOT})
@@ -102,9 +136,11 @@ endif(NOT IOS)
 
 
 option(BUILD_PYTHON_BINDINGS "Build python bindings" OFF)
 option(BUILD_PYTHON_BINDINGS "Build python bindings" OFF)
 option(BUILD_LUA_BINDINGS "Build Lua bindings" OFF)
 option(BUILD_LUA_BINDINGS "Build Lua bindings" OFF)
+
 if(APPLE)
 if(APPLE)
 	option(BUILD_FRAMEWORK "Build Framework bundle for OSX" OFF)
 	option(BUILD_FRAMEWORK "Build Framework bundle for OSX" OFF)
 endif()
 endif()
+
 option(BUILD_SAMPLES "Build samples" OFF)
 option(BUILD_SAMPLES "Build samples" OFF)
 if(WIN32)
 if(WIN32)
 	option(SKIP_DIRECTX_SAMPLES "Skip build of all DirectX related samples.  Only applies if BUILD_SAMPLES is ON" OFF)
 	option(SKIP_DIRECTX_SAMPLES "Skip build of all DirectX related samples.  Only applies if BUILD_SAMPLES is ON" OFF)
@@ -112,28 +148,29 @@ if(WIN32)
 	option(SKIP_DIRECTX10_SAMPLE "Skip build of DirectX 10 related sample.  Only applies if BUILD_SAMPLES is ON and SKIP_DIRECTX_SAMPLES is OFF" OFF)
 	option(SKIP_DIRECTX10_SAMPLE "Skip build of DirectX 10 related sample.  Only applies if BUILD_SAMPLES is ON and SKIP_DIRECTX_SAMPLES is OFF" OFF)
 endif()
 endif()
 
 
-if(IOS)
-	if(BUILD_SHARED_LIBS)
-		message(FATAL_ERROR "BUILD_SHARED_LIBS must be OFF for iOS builds.  iOS does not support shared libraries.")
-	endif(BUILD_SHARED_LIBS)
-endif(IOS)
+if(APPLE)
+	if(IOS)
+		if(BUILD_SHARED_LIBS)
+			message(FATAL_ERROR "BUILD_SHARED_LIBS must be OFF for iOS builds.  iOS does not support shared libraries.")
+		endif(BUILD_SHARED_LIBS)
+	endif(IOS)
 
 
-if(BUILD_FRAMEWORK)
-	if(APPLE)
+	if(BUILD_FRAMEWORK)
 		if(NOT "${CMAKE_GENERATOR}" STREQUAL "Xcode")
 		if(NOT "${CMAKE_GENERATOR}" STREQUAL "Xcode")
 			message(FATAL_ERROR "You should use Xcode generator with BUILD_FRAMEWORK enabled")
 			message(FATAL_ERROR "You should use Xcode generator with BUILD_FRAMEWORK enabled")
 		endif()
 		endif()
-		set(CMAKE_OSX_ARCHITECTURES "$(ARCHS_STANDARD_32_64_BIT)")
 		if(NOT BUILD_SHARED_LIBS)
 		if(NOT BUILD_SHARED_LIBS)
 			message(FATAL_ERROR "BUILD_SHARED_LIBS must be ON with BUILD_FRAMEWORK enabled")
 			message(FATAL_ERROR "BUILD_SHARED_LIBS must be ON with BUILD_FRAMEWORK enabled")
 		endif()
 		endif()
-	else(APPLE)
+	endif()
+else(APPLE)
+	if(BUILD_FRAMEWORK)
 		message(FATAL_ERROR "BUILD_FRAMEWORK is only supported on Mac OS X with the Xcode generator")
 		message(FATAL_ERROR "BUILD_FRAMEWORK is only supported on Mac OS X with the Xcode generator")
-	endif(APPLE)
-endif()
+	endif()
+endif(APPLE)
 
 
 if(NOT BUILD_SHARED_LIBS)
 if(NOT BUILD_SHARED_LIBS)
-    add_definitions(-DSTATIC_LIB)
+	add_definitions(-DROCKET_STATIC_LIB)
 endif()
 endif()
 
 
 #on windows, check for VC10 and fix the multiple compile target issue.
 #on windows, check for VC10 and fix the multiple compile target issue.
@@ -239,19 +276,14 @@ foreach(library ${LIBRARIES})
                            SOVERSION ${LIBROCKET_VERSION_MAJOR}
                            SOVERSION ${LIBROCKET_VERSION_MAJOR}
     )
     )
     
     
-    if(APPLE)
-	if(NOT IOS)
-    		set_target_properties(${NAME} PROPERTIES
-    						OSX_ARCHITECTURES "i386;x86_64;"
-    		)
-	endif(NOT IOS)
-    endif(APPLE)
-
     install(TARGETS ${NAME}
     install(TARGETS ${NAME}
+            EXPORT libRocketTargets
             LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
             LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
             ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
             ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
             RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
             RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
     )
     )
+
+    set(ROCKET_EXPORTED_TARGETS ${ROCKET_EXPORTED_TARGETS} ${NAME})
 endforeach(library)
 endforeach(library)
 else(NOT BUILD_FRAMEWORK)
 else(NOT BUILD_FRAMEWORK)
 	#===================================
 	#===================================
@@ -286,9 +318,6 @@ else(NOT BUILD_FRAMEWORK)
 		SOVERSION ${LIBROCKET_VERSION_MAJOR}
 		SOVERSION ${LIBROCKET_VERSION_MAJOR}
 	)
 	)
 
 
-	set_target_properties(${NAME} PROPERTIES
-		OSX_ARCHITECTURES "$(ARCHS_STANDARD_32_64_BIT)"
-	)
 		set_property(SOURCE ${MASTER_PUB_HDR_FILES}
 		set_property(SOURCE ${MASTER_PUB_HDR_FILES}
 			PROPERTY MACOSX_PACKAGE_LOCATION Headers
 			PROPERTY MACOSX_PACKAGE_LOCATION Headers
 		)
 		)
@@ -312,11 +341,14 @@ else(NOT BUILD_FRAMEWORK)
 		)
 		)
 
 
     install(TARGETS ${NAME}
     install(TARGETS ${NAME}
+            EXPORT libRocketTargets
             LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
             LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
             ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
             ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
             RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
             RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
             FRAMEWORK DESTINATION Library/Frameworks
             FRAMEWORK DESTINATION Library/Frameworks
     )
     )
+
+    set(ROCKET_EXPORTED_TARGETS ${ROCKET_EXPORTED_TARGETS} ${NAME})
 endif(NOT BUILD_FRAMEWORK)
 endif(NOT BUILD_FRAMEWORK)
 
 
 # Build python bindings
 # Build python bindings
@@ -331,19 +363,13 @@ if(BUILD_PYTHON_BINDINGS)
                             ${Py${library}_PUB_HDR_FILES}
                             ${Py${library}_PUB_HDR_FILES}
         )
         )
 
 
-    if(APPLE)
-	if(NOT IOS)
-    		set_target_properties(${NAME} PROPERTIES
-    						OSX_ARCHITECTURES "$(ARCHS_STANDARD_32_64_BIT)"
-    		)
-	endif(NOT IOS)
-    endif(APPLE)
-
         set_target_properties(${NAME} PROPERTIES PREFIX "")
         set_target_properties(${NAME} PROPERTIES PREFIX "")
 
 
         install(TARGETS ${NAME}
         install(TARGETS ${NAME}
+                EXPORT libRocketTargets
                 LIBRARY DESTINATION ${PYTHON_INSTDIR}
                 LIBRARY DESTINATION ${PYTHON_INSTDIR}
         )
         )
+ 
     endforeach(library)
     endforeach(library)
 endif()
 endif()
 
 
@@ -364,19 +390,14 @@ if(BUILD_LUA_BINDINGS)
                            SOVERSION ${LIBROCKET_VERSION_MAJOR}
                            SOVERSION ${LIBROCKET_VERSION_MAJOR}
         )
         )
         
         
-    if(APPLE)
-	if(NOT IOS)
-    		set_target_properties(${NAME} PROPERTIES
-    						OSX_ARCHITECTURES "$(ARCHS_STANDARD_32_64_BIT)"
-    		)
-	endif(NOT IOS)
-    endif(APPLE)
-
         install(TARGETS ${NAME}
         install(TARGETS ${NAME}
+            EXPORT libRocketTargets
             LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
             LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
             ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
             ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
             RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
             RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
         )
         )
+        
+        set(ROCKET_EXPORTED_TARGETS ${ROCKET_EXPORTED_TARGETS} ${NAME})
     endforeach(library)
     endforeach(library)
 endif()
 endif()
 
 
@@ -447,7 +468,7 @@ endmacro()
 if(BUILD_SAMPLES)
 if(BUILD_SAMPLES)
     include(SampleFileList)
     include(SampleFileList)
 
 
-    set(samples treeview customlog drag loaddocument)
+    set(samples treeview customlog drag loaddocument bitmapfont)
     set(tutorials template datagrid datagrid_tree tutorial_drag)
     set(tutorials template datagrid datagrid_tree tutorial_drag)
     
     
 if(NOT BUILD_FRAMEWORK)
 if(NOT BUILD_FRAMEWORK)
@@ -605,16 +626,16 @@ endif(NOT BUILD_FRAMEWORK)
 	endif()
 	endif()
 
 
     message("-- Can SDL2 sample be built")
     message("-- Can SDL2 sample be built")
-    find_package(SDL)
-    if(SDL_FOUND)
-	find_package(SDL_image)
-	if(SDL_IMAGE_FOUND)
+    find_package(SDL2)
+    if(SDL2_FOUND)
+	find_package(SDL2_image)
+	if(SDL2_IMAGE_FOUND)
 		find_package(GLEW)
 		find_package(GLEW)
 		if(GLEW_FOUND)
 		if(GLEW_FOUND)
         		message("-- Can SDL2 sample be built - yes")
         		message("-- Can SDL2 sample be built - yes")
-			include_directories(${SDL_INCLUDE_DIR} ${GLEW_INCLUDE_DIR})
+			include_directories(${SDL2_INCLUDE_DIR} ${GLEW_INCLUDE_DIR})
 
 
-			bl_sample(sdl2 ${sample_LIBRARIES}  ${SDL_LIBRARY} ${SDL_IMAGE_LIBRARY} ${GLEW_LIBRARY})
+			bl_sample(sdl2 ${sample_LIBRARIES}  ${SDL2_LIBRARY} ${SDL2_IMAGE_LIBRARY} ${GLEW_LIBRARY})
 			# The samples always set this as their current working directory
 			# The samples always set this as their current working directory
 			install(DIRECTORY DESTINATION ${SAMPLES_DIR}/basic/sdl2)
 			install(DIRECTORY DESTINATION ${SAMPLES_DIR}/basic/sdl2)
 			install(TARGETS sdl2
 			install(TARGETS sdl2
@@ -790,3 +811,50 @@ if(BUILD_SAMPLES)
         )
         )
     endif()
     endif()
 endif()
 endif()
+
+#===================================
+# Generate Config.cmake files ======
+#===================================
+
+# Try to include helper module
+include(CMakePackageConfigHelpers OPTIONAL
+  RESULT_VARIABLE PkgHelpers_AVAILABLE)
+# guard against older versions of cmake which do not provide it
+if(PkgHelpers_AVAILABLE)
+
+  set (INCLUDE_INSTALL_DIR "include")
+  set (LIB_INSTALL_DIR "lib")
+  set (INCLUDE_DIR "${PROJECT_SOURCE_DIR}/Include")
+
+  # generate configuration for install tree
+  configure_package_config_file(libRocketConfig.cmake.install.in
+    ${CMAKE_CURRENT_BINARY_DIR}/install/libRocketConfig.cmake
+    INSTALL_DESTINATION ${LIB_INSTALL_DIR}/libRocket/cmake
+    PATH_VARS INCLUDE_INSTALL_DIR LIB_INSTALL_DIR)
+  write_basic_package_version_file(
+    ${CMAKE_CURRENT_BINARY_DIR}/install/libRocketConfigVersion.cmake
+    VERSION ${PROJECT_VERSION}
+    COMPATIBILITY SameMajorVersion )
+  install(FILES ${CMAKE_CURRENT_BINARY_DIR}/install/libRocketConfig.cmake
+    ${CMAKE_CURRENT_BINARY_DIR}/install/libRocketConfigVersion.cmake
+    DESTINATION ${LIB_INSTALL_DIR}/libRocket/cmake )
+  install(EXPORT libRocketTargets
+    DESTINATION ${LIB_INSTALL_DIR}/libRocket/cmake)
+
+  # generate configuration for build tree
+  configure_package_config_file(libRocketConfig.cmake.build.in
+    ${CMAKE_CURRENT_BINARY_DIR}/libRocketConfig.cmake
+    INSTALL_DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
+    PATH_VARS INCLUDE_DIR CMAKE_CURRENT_BINARY_DIR)
+  export(TARGETS ${ROCKET_EXPORTED_TARGETS}
+    FILE "${CMAKE_CURRENT_BINARY_DIR}/libRocketTargets.cmake")
+  write_basic_package_version_file(
+    ${CMAKE_CURRENT_BINARY_DIR}/libRocketConfigVersion.cmake
+    VERSION ${PROJECT_VERSION}
+    COMPATIBILITY SameMajorVersion )
+  set(libRocket_DIR "${CMAKE_CURRENT_BINARY_DIR}" CACHE PATH "The directory containing a CMake configuration file for libRocket.")
+else()
+  message("If you wish to use find_package(libRocket) in your own project to find libRocket library"
+    " please update cmake to version which provides CMakePackageConfighelpers module"
+    " or write generators for libRocketConfig.cmake by yourself.")
+endif()

+ 25 - 2
Build/cmake/FileList.cmake

@@ -36,10 +36,17 @@ set(Core_HDR_FILES
     ${PROJECT_SOURCE_DIR}/Source/Core/FontEffectOutlineInstancer.h
     ${PROJECT_SOURCE_DIR}/Source/Core/FontEffectOutlineInstancer.h
     ${PROJECT_SOURCE_DIR}/Source/Core/FontEffectShadow.h
     ${PROJECT_SOURCE_DIR}/Source/Core/FontEffectShadow.h
     ${PROJECT_SOURCE_DIR}/Source/Core/FontEffectShadowInstancer.h
     ${PROJECT_SOURCE_DIR}/Source/Core/FontEffectShadowInstancer.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/FontFace.h
     ${PROJECT_SOURCE_DIR}/Source/Core/FontFaceHandle.h
     ${PROJECT_SOURCE_DIR}/Source/Core/FontFaceHandle.h
     ${PROJECT_SOURCE_DIR}/Source/Core/FontFaceLayer.h
     ${PROJECT_SOURCE_DIR}/Source/Core/FontFaceLayer.h
-    ${PROJECT_SOURCE_DIR}/Source/Core/FontFamily.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/BitmapFont/BitmapFontDefinitions.h
+    ${PROJECT_SOURCE_DIR}/Source/Core/BitmapFont/FontParser.h
+    ${PROJECT_SOURCE_DIR}/Source/Core/BitmapFont/FontFace.h
+    ${PROJECT_SOURCE_DIR}/Source/Core/BitmapFont/FontFaceHandle.h
+    ${PROJECT_SOURCE_DIR}/Source/Core/BitmapFont/FontFaceLayer.h
+    ${PROJECT_SOURCE_DIR}/Source/Core/BitmapFont/FontFamily.h
     ${PROJECT_SOURCE_DIR}/Source/Core/GeometryDatabase.h
     ${PROJECT_SOURCE_DIR}/Source/Core/GeometryDatabase.h
     ${PROJECT_SOURCE_DIR}/Source/Core/LayoutBlockBox.h
     ${PROJECT_SOURCE_DIR}/Source/Core/LayoutBlockBox.h
     ${PROJECT_SOURCE_DIR}/Source/Core/LayoutBlockBoxSpace.h
     ${PROJECT_SOURCE_DIR}/Source/Core/LayoutBlockBoxSpace.h
@@ -128,7 +135,12 @@ set(Core_PUB_HDR_FILES
     ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/FontDatabase.h
     ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/FontDatabase.h
     ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/FontEffect.h
     ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/FontEffect.h
     ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/FontEffectInstancer.h
     ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/FontEffectInstancer.h
+    ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/FontFace.h
+    ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/FontFamily.h
     ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/FontGlyph.h
     ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/FontGlyph.h
+    ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/FontProvider.h
+    ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/FreeType/FontProvider.h
+    ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/BitmapFont/FontProvider.h
     ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/Geometry.h
     ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/Geometry.h
     ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/GeometryUtilities.h
     ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/GeometryUtilities.h
     ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/Header.h
     ${PROJECT_SOURCE_DIR}/Include/Rocket/Core/Header.h
@@ -233,6 +245,17 @@ set(Core_SRC_FILES
     ${PROJECT_SOURCE_DIR}/Source/Core/FontFaceHandle.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/FontFaceHandle.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/FontFaceLayer.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/FontFaceLayer.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/FontFamily.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/FontFamily.cpp
+    ${PROJECT_SOURCE_DIR}/Source/Core/FontProvider.cpp
+    ${PROJECT_SOURCE_DIR}/Source/Core/FreeType/FontFace.cpp
+    ${PROJECT_SOURCE_DIR}/Source/Core/FreeType/FontFaceHandle.cpp
+    ${PROJECT_SOURCE_DIR}/Source/Core/FreeType/FontFamily.cpp
+    ${PROJECT_SOURCE_DIR}/Source/Core/FreeType/FontProvider.cpp
+    ${PROJECT_SOURCE_DIR}/Source/Core/BitmapFont/FontParser.cpp
+    ${PROJECT_SOURCE_DIR}/Source/Core/BitmapFont/FontFace.cpp
+    ${PROJECT_SOURCE_DIR}/Source/Core/BitmapFont/FontFaceHandle.cpp
+    ${PROJECT_SOURCE_DIR}/Source/Core/BitmapFont/FontFaceLayer.cpp
+    ${PROJECT_SOURCE_DIR}/Source/Core/BitmapFont/FontFamily.cpp
+    ${PROJECT_SOURCE_DIR}/Source/Core/BitmapFont/FontProvider.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/Geometry.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/Geometry.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/GeometryDatabase.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/GeometryDatabase.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/GeometryUtilities.cpp
     ${PROJECT_SOURCE_DIR}/Source/Core/GeometryUtilities.cpp

+ 165 - 0
Build/cmake/FindSDL2.cmake

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

+ 119 - 0
Build/cmake/FindSDL2_image.cmake

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

+ 4 - 7
Build/cmake/Platform/iOS.cmake

@@ -46,11 +46,6 @@ if (CMAKE_UNAME)
 	string (REGEX REPLACE "^([0-9]+)\\.([0-9]+).*$" "\\1" DARWIN_MAJOR_VERSION "${CMAKE_HOST_SYSTEM_VERSION}")
 	string (REGEX REPLACE "^([0-9]+)\\.([0-9]+).*$" "\\1" DARWIN_MAJOR_VERSION "${CMAKE_HOST_SYSTEM_VERSION}")
 endif (CMAKE_UNAME)
 endif (CMAKE_UNAME)
 
 
-# Force the compilers to gcc for iOS
-include (CMakeForceCompiler)
-CMAKE_FORCE_C_COMPILER (gcc gcc)
-CMAKE_FORCE_CXX_COMPILER (g++ g++)
-
 # Skip the platform compiler checks for cross compiling
 # Skip the platform compiler checks for cross compiling
 set (CMAKE_CXX_COMPILER_WORKS TRUE)
 set (CMAKE_CXX_COMPILER_WORKS TRUE)
 set (CMAKE_C_COMPILER_WORKS TRUE)
 set (CMAKE_C_COMPILER_WORKS TRUE)
@@ -146,10 +141,12 @@ set (CMAKE_OSX_SYSROOT ${CMAKE_IOS_SDK_ROOT} CACHE PATH "Sysroot used for iOS su
 if (${IOS_PLATFORM} STREQUAL "OS")
 if (${IOS_PLATFORM} STREQUAL "OS")
 	set (IOS_ARCH armv6 armv7 armv7s arm64)
 	set (IOS_ARCH armv6 armv7 armv7s arm64)
 else (${IOS_PLATFORM} STREQUAL "OS")
 else (${IOS_PLATFORM} STREQUAL "OS")
-	set (IOS_ARCH i386)
+	set (IOS_ARCH i386 x86_64)
 endif (${IOS_PLATFORM} STREQUAL "OS")
 endif (${IOS_PLATFORM} STREQUAL "OS")
 
 
-set (CMAKE_OSX_ARCHITECTURES ${IOS_ARCH} CACHE string  "Build architecture for iOS")
+if (NOT DEFINED CMAKE_OSX_ARCHITECTURES)
+	set (CMAKE_OSX_ARCHITECTURES ${IOS_ARCH} CACHE string  "Build architecture for iOS")
+endif (NOT DEFINED CMAKE_OSX_ARCHITECTURES)
 
 
 # Set the find root to the iOS developer roots and to user defined paths
 # Set the find root to the iOS developer roots and to user defined paths
 set (CMAKE_FIND_ROOT_PATH ${CMAKE_IOS_DEVELOPER_ROOT} ${CMAKE_IOS_SDK_ROOT} ${CMAKE_PREFIX_PATH} CACHE string  "iOS find search path root")
 set (CMAKE_FIND_ROOT_PATH ${CMAKE_IOS_DEVELOPER_ROOT} ${CMAKE_IOS_SDK_ROOT} ${CMAKE_PREFIX_PATH} CACHE string  "iOS find search path root")

+ 7 - 0
Build/cmake/SampleFileList.cmake

@@ -45,6 +45,13 @@ set(loaddocument_SRC_FILES
     ${PROJECT_SOURCE_DIR}/Samples/basic/loaddocument/src/main.cpp
     ${PROJECT_SOURCE_DIR}/Samples/basic/loaddocument/src/main.cpp
 )
 )
 
 
+set(bitmapfont_HDR_FILES
+)
+
+set(bitmapfont_SRC_FILES
+    ${PROJECT_SOURCE_DIR}/Samples/basic/bitmapfont/src/main.cpp
+)
+
 set(ogre3d_HDR_FILES
 set(ogre3d_HDR_FILES
     ${PROJECT_SOURCE_DIR}/Samples/basic/ogre3d/src/RenderInterfaceOgre3D.h
     ${PROJECT_SOURCE_DIR}/Samples/basic/ogre3d/src/RenderInterfaceOgre3D.h
     ${PROJECT_SOURCE_DIR}/Samples/basic/ogre3d/src/RocketApplication.h
     ${PROJECT_SOURCE_DIR}/Samples/basic/ogre3d/src/RocketApplication.h

+ 11 - 0
Build/libRocketConfig.cmake.build.in

@@ -0,0 +1,11 @@
+@PACKAGE_INIT@
+
+set_and_check(libRocket_INCLUDE_DIRS "@PACKAGE_INCLUDE_DIR@")
+set(libRocket_LIBRARIES @ROCKET_EXPORTED_TARGETS@)
+list(GET libRocket_LIBRARIES 0 ROCKET_FIRST_TARGET)
+
+if(NOT (TARGET ${ROCKET_FIRST_TARGET}))
+  include("${CMAKE_CURRENT_LIST_DIR}/libRocketTargets.cmake")
+endif()
+
+check_required_components(libRocket)

+ 7 - 0
Build/libRocketConfig.cmake.install.in

@@ -0,0 +1,7 @@
+@PACKAGE_INIT@
+
+set_and_check(libRocket_INCLUDE_DIRS "@PACKAGE_INCLUDE_INSTALL_DIR@")
+set(libRocket_LIBRARIES @ROCKET_EXPORTED_TARGETS@)
+include("${CMAKE_CURRENT_LIST_DIR}/libRocketTargets.cmake")
+
+check_required_components(libRocket)

+ 120 - 0
Dependencies/osx-depends.sh

@@ -0,0 +1,120 @@
+#!/usr/bin/env sh
+
+BUILD_FREETYPE2=YES
+BUILD_BOOST_PYTHON=YES
+BUILD_LUA=YES
+BUILD_PLATFORM=osx
+
+
+#Get depends root directory
+
+pushd `dirname $0` > /dev/null
+SCRIPT_PATH=`pwd`
+popd > /dev/null
+
+DEPS_DIR=${SCRIPT_PATH}
+
+BUILD_OUTPUTDIR=${DEPS_DIR}/${BUILD_PLATFORM}
+
+if [ ! -d "${BUILD_OUTPUTDIR}" ]; then
+	mkdir "${BUILD_OUTPUTDIR}"
+fi
+if [ ! -d "${BUILD_OUTPUTDIR}/lib" ]; then
+	mkdir "${BUILD_OUTPUTDIR}/lib"
+fi
+if [ ! -d "${BUILD_OUTPUTDIR}/include" ]; then
+	mkdir "${BUILD_OUTPUTDIR}/include"
+fi
+
+create_ios_outdir_lipo()
+{
+        for lib_i386 in `find $LOCAL_OUTDIR/i386 -name "lib*.a"`; do
+                lib_arm7=`echo $lib_i386 | sed "s/i386/arm7/g"`
+                lib_arm7s=`echo $lib_i386 | sed "s/i386/arm7s/g"`
+                lib=`echo $lib_i386 | sed "s/i386//g"`
+                xcrun -sdk iphoneos lipo -arch armv7s $lib_arm7s -arch armv7 $lib_arm7 -create -output $lib
+        done
+}
+
+build_freetype()
+{
+
+	cd "${DEPS_DIR}"
+	if [ ! -d "freetype2" ]; then
+		git clone --recursive git://git.sv.nongnu.org/freetype/freetype2.git freetype2
+	fi
+
+	cd freetype2
+
+	cmake CMakeLists.txt -DBUILD_SHARED_LIBS:BOOL=false
+	make
+
+	cmake CMakeLists.txt -DBUILD_SHARED_LIBS:BOOL=true
+	make
+
+	if [ ! -d "${BUILD_OUTPUTDIR}/include/freetype2" ]; then
+		mkdir "${BUILD_OUTPUTDIR}/include/freetype2"
+	fi
+	cp -Rp include/* "${BUILD_OUTPUTDIR}/include/freetype2/"
+	cp libfreetype.a "${BUILD_OUTPUTDIR}/lib/"
+	cp libfreetype.dylib "${BUILD_OUTPUTDIR}/lib/"
+
+	cd "${DEPS_DIR}"
+}
+
+build_boostpython()
+{
+	cd "${DEPS_DIR}"
+	if [ ! -d "boost" ]; then
+		git clone --recursive https://github.com/boostorg/boost.git boost
+	fi
+
+	cd boost
+
+	git submodule foreach 'git clean -fdx; git reset --hard'
+	git clean -fdx
+
+	./bootstrap.sh
+	./b2 architecture=x86 address-model=32_64 --with-python
+	##./b2 architecture=x86 address-model=32_64 link=shared --with-python
+	##./b2 architecture=x86 address-model=32_64 link=static --with-python
+
+
+	cp libs/python/include/boost/python.hpp boost/
+	cp libs/utility/include/boost/utility/value_init.hpp boost/utility/
+	cp libs/lexical_cast/include/boost/lexical_cast.hpp boost/
+cp -R libs/lexical_cast/include/boost/lexical_cast boost/
+	cp libs/lexical_cast/include/boost/detail/lcast_precision.hpp boost/detail/
+#	mkdir -p boost/math
+#	cp libs/math/include/boost/math/special_functions/sign.hpp boost/math/special_functions/
+#	cp libs/math/include/boost/math/special_functions/math_fwd.hpp boost/math/special_functions/
+#	cp libs/math/include/boost/math/special_functions/detail/round_fwd.hpp boost/math/special_functions/detail/
+#	cp libs/math/include/boost/math/special_functions/detail/fp_traits.hpp boost/math/special_functions/detail/
+	cp -R libs/math/include/boost/math boost/math
+
+#	mkdir -p boost/math/tools
+#	cp libs/math/include/boost/math/tools/config.hpp boost/math/tools/
+#	cp libs/math/include/boost/math/tools/user.hpp boost/math/tools/
+#	cp libs/math/include/boost/math/tools/promotion.hpp boost/math/tools/
+	mkdir -p boost/math/policies
+	cp libs/math/include/boost/math/policies/policy.hpp boost/math/policies/
+
+	cp libs/predef/include/boost/detail/endian.hpp boost/detail/
+
+	cp libs/math/include/boost/math/special_functions/fpclassify.hpp boost/math/special_functions/
+
+	cp libs/math/include/boost/math/tools/real_cast.hpp boost/math/tools/
+
+	cp libs/lexical_cast/include/boost/detail/basic_pointerbuf.hpp boost/detail/
+
+	cp libs/foreach/include/boost/foreach.hpp boost/
+
+	cp -R boost "${BUILD_OUTPUTDIR}/include/"
+	cp -R stage/lib/* "${BUILD_OUTPUTDIR}/lib/"
+	cd "${DEPS_DIR}"
+}
+
+
+
+build_freetype
+build_boostpython

+ 6 - 1
Include/Rocket/Controls/Header.h

@@ -30,7 +30,12 @@
 
 
 #include "../Core/Platform.h"
 #include "../Core/Platform.h"
 
 
-#if !defined STATIC_LIB
+#ifdef STATIC_LIB
+	#define ROCKET_STATIC_LIB
+	#pragma message("DEPRECATED: STATIC_LIB macro has been deprecated in favor of ROCKET_STATIC_LIB and support will be removed in a future release")
+#endif
+
+#if !defined ROCKET_STATIC_LIB
 	#ifdef ROCKET_PLATFORM_WIN32
 	#ifdef ROCKET_PLATFORM_WIN32
 		#ifdef RocketControls_EXPORTS
 		#ifdef RocketControls_EXPORTS
 			#define ROCKETCONTROLS_API __declspec(dllexport)
 			#define ROCKETCONTROLS_API __declspec(dllexport)

+ 6 - 1
Include/Rocket/Controls/Lua/Header.h

@@ -34,7 +34,12 @@
 #undef ROCKETLUA_API
 #undef ROCKETLUA_API
 #endif
 #endif
 
 
-#if !defined STATIC_LIB
+#ifdef STATIC_LIB
+	#define ROCKET_STATIC_LIB
+	#pragma message("DEPRECATED: STATIC_LIB macro has been deprecated in favor of ROCKET_STATIC_LIB and support will be removed in a future release")
+#endif
+
+#if !defined ROCKET_STATIC_LIB
 	#ifdef ROCKET_PLATFORM_WIN32
 	#ifdef ROCKET_PLATFORM_WIN32
 		#if defined RocketCoreLua_EXPORTS 
 		#if defined RocketCoreLua_EXPORTS 
 			#define ROCKETLUA_API __declspec(dllexport)
 			#define ROCKETLUA_API __declspec(dllexport)

+ 101 - 0
Include/Rocket/Core/BitmapFont/FontProvider.h

@@ -0,0 +1,101 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * 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 ROCKETCOREBITMAPFONTFONTPROVIDER_H
+#define ROCKETCOREBITMAPFONTFONTPROVIDER_H
+
+#include "../StringUtilities.h"
+#include "../Font.h"
+#include "../FontProvider.h"
+
+namespace Rocket {
+namespace Core {
+
+
+class FontEffect;
+class FontFaceHandle;
+class PropertyDictionary;
+
+namespace BitmapFont {
+
+class FontFamily;
+
+/**
+    The font database contains all font families currently in use by Rocket.
+    @author Peter Curry
+ */
+
+class ROCKETCORE_API FontProvider : public Rocket::Core::FontProvider
+{
+public:
+    static bool Initialise();
+    static void Shutdown();
+
+    /// 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.
+    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, Font::Style style, Font::Weight 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, Font::Style style, Font::Weight weight);
+
+private:
+    FontProvider(void);
+    ~FontProvider(void);
+
+    // Adds a loaded face to the appropriate font family.
+    bool AddFace(void* face, const String& family, Font::Style style, Font::Weight weight, bool release_stream);
+    // Loads a FreeType face.
+    void* LoadFace(const String& file_name);
+    // Loads a FreeType face from memory.
+    void* LoadFace(const byte* data, int data_length, const String& source, bool local_data);
+
+    static FontProvider* instance;
+};
+
+}
+}
+}
+
+#endif

+ 2 - 0
Include/Rocket/Core/Element.h

@@ -227,6 +227,8 @@ public:
 	/// @return The value of this property for this element.
 	/// @return The value of this property for this element.
 	float ResolveProperty(const Property *property, float base_value);
 	float ResolveProperty(const Property *property, float base_value);
 
 
+	/// Returns 'top', 'bottom', 'left' and 'right' properties from element's style or local cache.
+	void GetOffsetProperties(const Property **top, const Property **bottom, const Property **left, const Property **right );
 	/// Returns 'border-width' properties from element's style or local cache.
 	/// Returns 'border-width' properties from element's style or local cache.
 	void GetBorderWidthProperties(const Property **border_top_width, const Property **border_bottom_width, const Property **border_left_width, const Property **border_right_width);
 	void GetBorderWidthProperties(const Property **border_top_width, const Property **border_bottom_width, const Property **border_left_width, const Property **border_right_width);
 	/// Returns 'margin' properties from element's style or local cache.
 	/// Returns 'margin' properties from element's style or local cache.

+ 17 - 10
Include/Rocket/Core/FontDatabase.h

@@ -31,6 +31,7 @@
 #include "StringUtilities.h"
 #include "StringUtilities.h"
 #include "Header.h"
 #include "Header.h"
 #include "Font.h"
 #include "Font.h"
+#include "FontProvider.h"
 
 
 namespace Rocket {
 namespace Rocket {
 namespace Core {
 namespace Core {
@@ -49,6 +50,13 @@ class PropertyDictionary;
 class ROCKETCORE_API FontDatabase
 class ROCKETCORE_API FontDatabase
 {
 {
 public:
 public:
+
+    enum FontProviderType
+    {
+        FreeType = 0,
+        BitmapFont
+    };
+
 	static bool Initialise();
 	static bool Initialise();
 	static void Shutdown();
 	static void Shutdown();
 
 
@@ -67,7 +75,7 @@ public:
 	/// @param[in] data The font data.
 	/// @param[in] data The font data.
 	/// @param[in] data_length Length of the data.
 	/// @param[in] data_length Length of the data.
 	/// @return True if the face was loaded successfully, false otherwise.
 	/// @return True if the face was loaded successfully, false otherwise.
-	static bool LoadFontFace(const byte* data, int data_length);
+    static bool LoadFontFace(FontProviderType font_provider_type, const byte* data, int data_length);
 	/// Adds a new font face to the database, loading from memory.
 	/// Adds a new font face to the database, loading from memory.
 	/// @param[in] data The font data.
 	/// @param[in] data The font data.
 	/// @param[in] data_length Length of the data.
 	/// @param[in] data_length Length of the data.
@@ -75,7 +83,7 @@ public:
 	/// @param[in] style The style of the face (normal or italic).
 	/// @param[in] style The style of the face (normal or italic).
 	/// @param[in] weight The weight of the face (normal or bold).
 	/// @param[in] weight The weight of the face (normal or bold).
 	/// @return True if the face was loaded successfully, false otherwise.
 	/// @return True if the face was loaded successfully, false otherwise.
-	static bool LoadFontFace(const byte* data, int data_length, const String& family, Font::Style style, Font::Weight weight);
+    static bool LoadFontFace(FontProviderType font_provider_type, const byte* data, int data_length, const String& family, Font::Style style, Font::Weight weight);
 
 
 	/// Returns a handle to a font face that can be used to position and render text. This will return the closest match
 	/// 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
 	/// it can find, but in the event a font family is requested that does not exist, NULL will be returned instead of a
@@ -99,20 +107,19 @@ public:
 	/// @param[in] The effect to release.
 	/// @param[in] The effect to release.
 	static void ReleaseFontEffect(const FontEffect* effect);
 	static void ReleaseFontEffect(const FontEffect* effect);
 
 
+    static void AddFontProvider(FontProvider * provider);
+
+    static void RemoveFontProvider(FontProvider * provider);
+
 private:
 private:
 	FontDatabase(void);
 	FontDatabase(void);
 	~FontDatabase(void);
 	~FontDatabase(void);
 
 
-	// Adds a loaded face to the appropriate font family.
-	bool AddFace(void* face, const String& family, Font::Style style, Font::Weight weight, bool release_stream);
-	// Loads a FreeType face.
-	void* LoadFace(const String& file_name);
-	// Loads a FreeType face from memory.
-	void* LoadFace(const byte* data, int data_length, const String& source, bool local_data);
+    static FontProviderType GetFontProviderType(const String& file_name);
 
 
-	typedef std::map< String, FontFamily*, StringUtilities::StringComparei > FontFamilyMap;
-	FontFamilyMap font_families;
+    typedef std::vector< FontProvider *> FontProviderTable;
 
 
+    static FontProviderTable font_provider_table;
 	static FontDatabase* instance;
 	static FontDatabase* instance;
 };
 };
 
 

+ 6 - 9
Source/Core/FontFace.h → Include/Rocket/Core/FontFace.h

@@ -28,9 +28,7 @@
 #ifndef ROCKETCOREFONTFACE_H
 #ifndef ROCKETCOREFONTFACE_H
 #define ROCKETCOREFONTFACE_H
 #define ROCKETCOREFONTFACE_H
 
 
-#include "../../Include/Rocket/Core/Font.h"
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include "Font.h"
 
 
 namespace Rocket {
 namespace Rocket {
 namespace Core {
 namespace Core {
@@ -44,8 +42,8 @@ class FontFaceHandle;
 class FontFace
 class FontFace
 {
 {
 public:
 public:
-	FontFace(FT_Face face, Font::Style style, Font::Weight weight, bool release_stream);
-	~FontFace();
+    FontFace(Font::Style style, Font::Weight weight, bool release_stream);
+    virtual ~FontFace();
 
 
 	/// Returns the style of the font face.
 	/// Returns the style of the font face.
 	/// @return The font face's style.
 	/// @return The font face's style.
@@ -58,14 +56,13 @@ public:
 	/// @param[in] charset The set of characters in the handle, as a comma-separated list of unicode ranges.
 	/// @param[in] charset The set of characters in the handle, as a comma-separated list of unicode ranges.
 	/// @param[in] size The size of the desired handle, in points.
 	/// @param[in] size The size of the desired handle, in points.
 	/// @return The shared font handle.
 	/// @return The shared font handle.
-	FontFaceHandle* GetHandle(const String& charset, int size);
+    virtual FontFaceHandle* GetHandle(const String& charset, int size) = 0;
 
 
 	/// Releases the face's FreeType face structure. This will mean handles for new sizes cannot be constructed,
 	/// Releases the face's FreeType face structure. This will mean handles for new sizes cannot be constructed,
 	/// but existing ones can still be fetched.
 	/// but existing ones can still be fetched.
-	void ReleaseFace();
+    virtual void ReleaseFace() = 0;
 
 
-private:
-	FT_Face face;
+protected:
 	Font::Style style;
 	Font::Style style;
 	Font::Weight weight;
 	Font::Weight weight;
 
 

+ 6 - 7
Source/Core/FontFamily.h → Include/Rocket/Core/FontFamily.h

@@ -28,9 +28,8 @@
 #ifndef ROCKETCOREFONTFAMILY_H
 #ifndef ROCKETCOREFONTFAMILY_H
 #define ROCKETCOREFONTFAMILY_H
 #define ROCKETCOREFONTFAMILY_H
 
 
-#include "../../Include/Rocket/Core/Font.h"
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <Rocket/Core/StringUtilities.h>
+#include "Font.h"
 
 
 namespace Rocket {
 namespace Rocket {
 namespace Core {
 namespace Core {
@@ -46,7 +45,7 @@ class FontFamily
 {
 {
 public:
 public:
 	FontFamily(const String& name);
 	FontFamily(const String& name);
-	~FontFamily();
+    virtual ~FontFamily();
 
 
 	/// Adds a new face to the family.
 	/// Adds a new face to the family.
 	/// @param[in] ft_face The previously loaded FreeType face.
 	/// @param[in] ft_face The previously loaded FreeType face.
@@ -54,7 +53,7 @@ public:
 	/// @param[in] weight The weight of the new face.
 	/// @param[in] weight The weight of the new face.
 	/// @param[in] release_stream True if the application must free the face's memory stream.
 	/// @param[in] release_stream True if the application must free the face's memory stream.
 	/// @return True if the face was loaded successfully, false otherwise.
 	/// @return True if the face was loaded successfully, false otherwise.
-	bool AddFace(FT_Face ft_face, Font::Style style, Font::Weight weight, bool release_stream);
+    virtual bool AddFace(void* ft_face, Font::Style style, Font::Weight weight, bool release_stream) = 0;
 
 
 	/// Returns a handle to the most appropriate font in the family, at the correct size.
 	/// Returns a handle to the most appropriate font in the family, at the correct size.
 	/// @param[in] charset The set of characters in the handle, as a comma-separated list of unicode ranges.
 	/// @param[in] charset The set of characters in the handle, as a comma-separated list of unicode ranges.
@@ -62,9 +61,9 @@ public:
 	/// @param[in] weight The weight of the desired handle.
 	/// @param[in] weight The weight of the desired handle.
 	/// @param[in] size The size of desired handle, in points.
 	/// @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.
 	/// @return A valid handle if a matching (or closely matching) font face was found, NULL otherwise.
-	FontFaceHandle* GetFaceHandle(const String& charset, Font::Style style, Font::Weight weight, int size);
+    FontFaceHandle* GetFaceHandle(const String& charset, Font::Style style, Font::Weight weight, int size);
 
 
-private:
+protected:
 	String name;
 	String name;
 
 
 	typedef std::vector< FontFace* > FontFaceList;
 	typedef std::vector< FontFace* > FontFaceList;

+ 70 - 0
Include/Rocket/Core/FontProvider.h

@@ -0,0 +1,70 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * 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 ROCKETCOREFONTPROVIDER_H
+#define ROCKETCOREFONTPROVIDER_H
+
+#include <Rocket/Core/StringUtilities.h>
+#include <Rocket/Core/Font.h>
+#include <Rocket/Core/Header.h>
+
+namespace Rocket {
+namespace Core {
+
+class FontFaceHandle;
+class FontFamily;
+
+/**
+    The font database contains all font families currently in use by Rocket.
+    @author Peter Curry
+ */
+
+class ROCKETCORE_API FontProvider
+{
+public:
+
+    /// 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.
+    FontFaceHandle* GetFontFaceHandle(const String& family, const String& charset, Font::Style style, Font::Weight weight, int size);
+
+protected:
+
+    typedef std::map< String, FontFamily*, StringUtilities::StringComparei > FontFamilyMap;
+    FontFamilyMap font_families;
+};
+
+}
+}
+
+#endif

+ 101 - 0
Include/Rocket/Core/FreeType/FontProvider.h

@@ -0,0 +1,101 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * 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 ROCKETCOREFREETYPEFONTPROVIDER_H
+#define ROCKETCOREFREETYPEFONTPROVIDER_H
+
+#include "../StringUtilities.h"
+#include "../Font.h"
+#include "../FontProvider.h"
+
+namespace Rocket {
+namespace Core {
+
+
+class FontEffect;
+class FontFaceHandle;
+class PropertyDictionary;
+
+namespace FreeType {
+
+class FontFamily;
+
+/**
+    The font database contains all font families currently in use by Rocket.
+    @author Peter Curry
+ */
+
+class ROCKETCORE_API FontProvider : public Rocket::Core::FontProvider
+{
+public:
+    static bool Initialise();
+    static void Shutdown();
+
+    /// 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.
+    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, Font::Style style, Font::Weight 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, Font::Style style, Font::Weight weight);
+
+private:
+    FontProvider(void);
+    ~FontProvider(void);
+
+    // Adds a loaded face to the appropriate font family.
+    bool AddFace(void* face, const String& family, Font::Style style, Font::Weight weight, bool release_stream);
+    // Loads a FreeType face.
+    void* LoadFace(const String& file_name);
+    // Loads a FreeType face from memory.
+    void* LoadFace(const byte* data, int data_length, const String& source, bool local_data);
+
+    static FontProvider* instance;
+};
+
+}
+}
+}
+
+#endif

+ 6 - 1
Include/Rocket/Core/Header.h

@@ -33,7 +33,12 @@
 // Note: Changing a ROCKETCORE_API_INLINE method
 // Note: Changing a ROCKETCORE_API_INLINE method
 // breaks ABI compatibility!!
 // breaks ABI compatibility!!
 
 
-#if !defined STATIC_LIB
+#ifdef STATIC_LIB
+	#define ROCKET_STATIC_LIB
+	#pragma message("DEPRECATED: STATIC_LIB macro has been deprecated in favor of ROCKET_STATIC_LIB and support will be removed in a future release")
+#endif
+
+#if !defined ROCKET_STATIC_LIB
 	#if defined ROCKET_PLATFORM_WIN32
 	#if defined ROCKET_PLATFORM_WIN32
 		#if defined RocketCore_EXPORTS
 		#if defined RocketCore_EXPORTS
 			#define ROCKETCORE_API __declspec(dllexport)
 			#define ROCKETCORE_API __declspec(dllexport)

+ 6 - 1
Include/Rocket/Core/Lua/Header.h

@@ -34,7 +34,12 @@
 #undef ROCKETLUA_API
 #undef ROCKETLUA_API
 #endif
 #endif
 
 
-#if !defined STATIC_LIB
+#ifdef STATIC_LIB
+	#define ROCKET_STATIC_LIB
+	#pragma message("DEPRECATED: STATIC_LIB macro has been deprecated in favor of ROCKET_STATIC_LIB and support will be removed in a future release")
+#endif
+
+#if !defined ROCKET_STATIC_LIB
 	#ifdef ROCKET_PLATFORM_WIN32
 	#ifdef ROCKET_PLATFORM_WIN32
 		#if defined RocketCoreLua_EXPORTS 
 		#if defined RocketCoreLua_EXPORTS 
 			#define ROCKETLUA_API __declspec(dllexport)
 			#define ROCKETLUA_API __declspec(dllexport)

+ 1 - 1
Include/Rocket/Core/Platform.h

@@ -48,7 +48,7 @@
 	#define ROCKET_DEBUG
 	#define ROCKET_DEBUG
 #endif
 #endif
 
 
-#if defined __LP64__ || defined _M_X64 || defined __MING64__ || defined _LP64
+#if defined __LP64__ || defined _M_X64 || defined __MINGW64__ || defined _LP64
     #define ROCKET_ARCH_64
     #define ROCKET_ARCH_64
 #else
 #else
     #define ROCKET_ARCH_32
     #define ROCKET_ARCH_32

+ 6 - 1
Include/Rocket/Core/Python/Header.h

@@ -30,7 +30,12 @@
 
 
 #include "../Platform.h"
 #include "../Platform.h"
 
 
-#if !defined STATIC_LIB
+#ifdef STATIC_LIB
+	#define ROCKET_STATIC_LIB
+	#pragma message("DEPRECATED: STATIC_LIB macro has been deprecated in favor of ROCKET_STATIC_LIB and support will be removed in a future release")
+#endif
+
+#if !defined ROCKET_STATIC_LIB
 #if defined ROCKET_PLATFORM_WIN32
 #if defined ROCKET_PLATFORM_WIN32
 	#if defined RocketCorePython_EXPORTS
 	#if defined RocketCorePython_EXPORTS
 		#define ROCKETCOREPYTHON_API __declspec(dllexport)
 		#define ROCKETCOREPYTHON_API __declspec(dllexport)

+ 6 - 1
Include/Rocket/Debugger/Header.h

@@ -30,7 +30,12 @@
 
 
 #include "../Core/Platform.h"
 #include "../Core/Platform.h"
 
 
-#if !defined STATIC_LIB
+#ifdef STATIC_LIB
+	#define ROCKET_STATIC_LIB
+	#pragma message("DEPRECATED: STATIC_LIB macro has been deprecated in favor of ROCKET_STATIC_LIB and support will be removed in a future release")
+#endif
+
+#if !defined ROCKET_STATIC_LIB
 	#ifdef ROCKET_PLATFORM_WIN32
 	#ifdef ROCKET_PLATFORM_WIN32
 		#ifdef RocketDebugger_EXPORTS
 		#ifdef RocketDebugger_EXPORTS
 			#define ROCKETDEBUGGER_API __declspec(dllexport)
 			#define ROCKETDEBUGGER_API __declspec(dllexport)

+ 270 - 0
Samples/assets/Arial.fnt

@@ -0,0 +1,270 @@
+<?xml version="1.0"?>
+<font>
+  <info face="Arial" size="26" bold="0" italic="0" src="Arial_0.tga"/>
+  <common lineHeight="26" base="26" scaleW="1024" scaleH="1024" />
+  <chars count="191">
+    <char id="32" x="170" y="40" width="1" height="1" xoffset="0" yoffset="21" xadvance="6" />
+    <char id="33" x="643" y="19" width="2" height="17" xoffset="3" yoffset="4" xadvance="8" />
+    <char id="34" x="63" y="41" width="6" height="6" xoffset="1" yoffset="4" xadvance="8" />
+    <char id="35" x="84" y="23" width="13" height="17" xoffset="0" yoffset="4" xadvance="13" />
+    <char id="36" x="511" y="0" width="11" height="20" xoffset="1" yoffset="3" xadvance="13" />
+    <char id="37" x="724" y="0" width="18" height="17" xoffset="1" yoffset="4" xadvance="20" />
+    <char id="38" x="56" y="23" width="13" height="17" xoffset="1" yoffset="4" xadvance="15" />
+    <char id="39" x="77" y="41" width="2" height="6" xoffset="1" yoffset="4" xadvance="4" />
+    <char id="40" x="91" y="0" width="5" height="22" xoffset="1" yoffset="4" xadvance="8" />
+    <char id="41" x="97" y="0" width="5" height="22" xoffset="2" yoffset="4" xadvance="8" />
+    <char id="42" x="54" y="41" width="8" height="7" xoffset="1" yoffset="4" xadvance="9" />
+    <char id="43" x="916" y="18" width="12" height="12" xoffset="1" yoffset="7" xadvance="13" />
+    <char id="44" x="80" y="41" width="2" height="5" xoffset="2" yoffset="19" xadvance="6" />
+    <char id="45" x="149" y="40" width="7" height="2" xoffset="0" yoffset="14" xadvance="8" />
+    <char id="46" x="167" y="40" width="2" height="2" xoffset="2" yoffset="19" xadvance="6" />
+    <char id="47" x="604" y="19" width="7" height="17" xoffset="0" yoffset="4" xadvance="6" />
+    <char id="48" x="273" y="22" width="11" height="17" xoffset="1" yoffset="4" xadvance="13" />
+    <char id="49" x="620" y="19" width="6" height="17" xoffset="3" yoffset="4" xadvance="13" />
+    <char id="50" x="285" y="22" width="11" height="17" xoffset="1" yoffset="4" xadvance="13" />
+    <char id="51" x="345" y="22" width="11" height="17" xoffset="1" yoffset="4" xadvance="13" />
+    <char id="52" x="441" y="22" width="11" height="17" xoffset="1" yoffset="4" xadvance="13" />
+    <char id="53" x="453" y="21" width="11" height="17" xoffset="1" yoffset="4" xadvance="13" />
+    <char id="54" x="189" y="22" width="11" height="17" xoffset="1" yoffset="4" xadvance="13" />
+    <char id="55" x="261" y="22" width="11" height="17" xoffset="1" yoffset="4" xadvance="13" />
+    <char id="56" x="201" y="22" width="11" height="17" xoffset="1" yoffset="4" xadvance="13" />
+    <char id="57" x="213" y="22" width="11" height="17" xoffset="1" yoffset="4" xadvance="13" />
+    <char id="58" x="913" y="18" width="2" height="13" xoffset="2" yoffset="8" xadvance="6" />
+    <char id="59" x="717" y="18" width="2" height="16" xoffset="2" yoffset="8" xadvance="6" />
+    <char id="60" x="941" y="18" width="10" height="11" xoffset="1" yoffset="7" xadvance="13" />
+    <char id="61" x="32" y="41" width="10" height="7" xoffset="1" yoffset="9" xadvance="13" />
+    <char id="62" x="952" y="18" width="10" height="11" xoffset="1" yoffset="7" xadvance="13" />
+    <char id="63" x="225" y="22" width="11" height="17" xoffset="1" yoffset="4" xadvance="13" />
+    <char id="64" x="0" y="0" width="21" height="22" xoffset="1" yoffset="4" xadvance="23" />
+    <char id="65" x="816" y="0" width="17" height="17" xoffset="-1" yoffset="4" xadvance="15" />
+    <char id="66" x="124" y="22" width="12" height="17" xoffset="2" yoffset="4" xadvance="15" />
+    <char id="67" x="919" y="0" width="15" height="17" xoffset="1" yoffset="4" xadvance="17" />
+    <char id="68" x="951" y="0" width="14" height="17" xoffset="2" yoffset="4" xadvance="17" />
+    <char id="69" x="163" y="22" width="12" height="17" xoffset="2" yoffset="4" xadvance="15" />
+    <char id="70" x="237" y="22" width="11" height="17" xoffset="2" yoffset="4" xadvance="14" />
+    <char id="71" x="869" y="0" width="16" height="17" xoffset="1" yoffset="4" xadvance="18" />
+    <char id="72" x="42" y="23" width="13" height="17" xoffset="2" yoffset="4" xadvance="17" />
+    <char id="73" x="640" y="19" width="2" height="17" xoffset="2" yoffset="4" xadvance="6" />
+    <char id="74" x="576" y="19" width="9" height="17" xoffset="1" yoffset="4" xadvance="12" />
+    <char id="75" x="996" y="0" width="14" height="17" xoffset="2" yoffset="4" xadvance="15" />
+    <char id="76" x="543" y="19" width="10" height="17" xoffset="2" yoffset="4" xadvance="13" />
+    <char id="77" x="935" y="0" width="15" height="17" xoffset="2" yoffset="4" xadvance="19" />
+    <char id="78" x="70" y="23" width="13" height="17" xoffset="2" yoffset="4" xadvance="17" />
+    <char id="79" x="852" y="0" width="16" height="17" xoffset="1" yoffset="4" xadvance="18" />
+    <char id="80" x="98" y="23" width="12" height="17" xoffset="2" yoffset="4" xadvance="15" />
+    <char id="81" x="560" y="0" width="16" height="18" xoffset="1" yoffset="4" xadvance="18" />
+    <char id="82" x="981" y="0" width="14" height="17" xoffset="2" yoffset="4" xadvance="17" />
+    <char id="83" x="28" y="23" width="13" height="17" xoffset="1" yoffset="4" xadvance="15" />
+    <char id="84" x="1011" y="0" width="12" height="17" xoffset="1" yoffset="4" xadvance="14" />
+    <char id="85" x="14" y="23" width="13" height="17" xoffset="2" yoffset="4" xadvance="17" />
+    <char id="86" x="798" y="0" width="17" height="17" xoffset="-1" yoffset="4" xadvance="15" />
+    <char id="87" x="657" y="0" width="23" height="17" xoffset="0" yoffset="4" xadvance="23" />
+    <char id="88" x="903" y="0" width="15" height="17" xoffset="0" yoffset="4" xadvance="15" />
+    <char id="89" x="966" y="0" width="14" height="17" xoffset="0" yoffset="4" xadvance="14" />
+    <char id="90" x="0" y="23" width="13" height="17" xoffset="0" yoffset="4" xadvance="14" />
+    <char id="91" x="108" y="0" width="4" height="22" xoffset="1" yoffset="4" xadvance="6" />
+    <char id="92" x="612" y="19" width="7" height="17" xoffset="0" yoffset="4" xadvance="6" />
+    <char id="93" x="103" y="0" width="4" height="22" xoffset="1" yoffset="4" xadvance="6" />
+    <char id="94" x="983" y="18" width="10" height="9" xoffset="1" yoffset="4" xadvance="12" />
+    <char id="95" x="111" y="41" width="14" height="2" xoffset="-1" yoffset="24" xadvance="13" />
+    <char id="96" x="106" y="41" width="4" height="3" xoffset="1" yoffset="4" xadvance="8" />
+    <char id="97" x="814" y="18" width="11" height="13" xoffset="1" yoffset="8" xadvance="13" />
+    <char id="98" x="477" y="21" width="10" height="17" xoffset="1" yoffset="4" xadvance="12" />
+    <char id="99" x="850" y="18" width="10" height="13" xoffset="1" yoffset="8" xadvance="12" />
+    <char id="100" x="565" y="19" width="10" height="17" xoffset="1" yoffset="4" xadvance="12" />
+    <char id="101" x="826" y="18" width="11" height="13" xoffset="1" yoffset="8" xadvance="13" />
+    <char id="102" x="595" y="19" width="8" height="17" xoffset="0" yoffset="4" xadvance="7" />
+    <char id="103" x="614" y="0" width="10" height="18" xoffset="1" yoffset="8" xadvance="12" />
+    <char id="104" x="554" y="19" width="10" height="17" xoffset="1" yoffset="4" xadvance="12" />
+    <char id="105" x="637" y="19" width="2" height="17" xoffset="1" yoffset="4" xadvance="5" />
+    <char id="106" x="85" y="0" width="5" height="22" xoffset="-2" yoffset="4" xadvance="4" />
+    <char id="107" x="249" y="22" width="11" height="17" xoffset="1" yoffset="4" xadvance="11" />
+    <char id="108" x="646" y="19" width="2" height="17" xoffset="1" yoffset="4" xadvance="4" />
+    <char id="109" x="771" y="18" width="16" height="13" xoffset="1" yoffset="8" xadvance="18" />
+    <char id="110" x="894" y="18" width="10" height="13" xoffset="1" yoffset="8" xadvance="12" />
+    <char id="111" x="802" y="18" width="11" height="13" xoffset="1" yoffset="8" xadvance="13" />
+    <char id="112" x="636" y="0" width="10" height="18" xoffset="1" yoffset="8" xadvance="12" />
+    <char id="113" x="591" y="0" width="11" height="18" xoffset="0" yoffset="8" xadvance="12" />
+    <char id="114" x="905" y="18" width="7" height="13" xoffset="1" yoffset="8" xadvance="8" />
+    <char id="115" x="883" y="18" width="10" height="13" xoffset="1" yoffset="8" xadvance="12" />
+    <char id="116" x="647" y="0" width="6" height="18" xoffset="0" yoffset="3" xadvance="6" />
+    <char id="117" x="861" y="18" width="10" height="13" xoffset="1" yoffset="8" xadvance="12" />
+    <char id="118" x="788" y="18" width="13" height="13" xoffset="-1" yoffset="8" xadvance="11" />
+    <char id="119" x="753" y="18" width="17" height="13" xoffset="-1" yoffset="8" xadvance="15" />
+    <char id="120" x="838" y="18" width="11" height="13" xoffset="0" yoffset="8" xadvance="11" />
+    <char id="121" x="577" y="0" width="13" height="18" xoffset="-1" yoffset="8" xadvance="11" />
+    <char id="122" x="872" y="18" width="10" height="13" xoffset="0" yoffset="8" xadvance="11" />
+    <char id="123" x="71" y="0" width="6" height="22" xoffset="1" yoffset="4" xadvance="8" />
+    <char id="124" x="113" y="0" width="2" height="22" xoffset="2" yoffset="4" xadvance="6" />
+    <char id="125" x="78" y="0" width="6" height="22" xoffset="1" yoffset="4" xadvance="8" />
+    <char id="126" x="83" y="41" width="11" height="4" xoffset="1" yoffset="11" xadvance="13" />
+    <char id="160" x="172" y="40" width="1" height="1" xoffset="0" yoffset="21" xadvance="6" />
+    <char id="161" x="654" y="0" width="2" height="18" xoffset="3" yoffset="8" xadvance="8" />
+    <char id="162" x="60" y="0" width="10" height="22" xoffset="1" yoffset="4" xadvance="13" />
+    <char id="163" x="111" y="23" width="12" height="17" xoffset="0" yoffset="4" xadvance="13" />
+    <char id="164" x="929" y="18" width="11" height="11" xoffset="1" yoffset="7" xadvance="13" />
+    <char id="165" x="176" y="22" width="12" height="17" xoffset="0" yoffset="4" xadvance="13" />
+    <char id="166" x="116" y="0" width="2" height="22" xoffset="2" yoffset="4" xadvance="6" />
+    <char id="167" x="48" y="0" width="11" height="22" xoffset="1" yoffset="4" xadvance="13" />
+    <char id="168" x="157" y="40" width="6" height="2" xoffset="1" yoffset="4" xadvance="8" />
+    <char id="169" x="762" y="0" width="17" height="17" xoffset="0" yoffset="4" xadvance="17" />
+    <char id="170" x="8" y="41" width="7" height="8" xoffset="1" yoffset="4" xadvance="9" />
+    <char id="171" x="973" y="18" width="9" height="10" xoffset="1" yoffset="10" xadvance="13" />
+    <char id="172" x="43" y="41" width="10" height="7" xoffset="1" yoffset="9" xadvance="13" />
+    <char id="173" x="141" y="40" width="7" height="2" xoffset="0" yoffset="14" xadvance="8" />
+    <char id="174" x="834" y="0" width="17" height="17" xoffset="0" yoffset="4" xadvance="17" />
+    <char id="175" x="126" y="40" width="14" height="2" xoffset="-1" yoffset="1" xadvance="13" />
+    <char id="176" x="70" y="41" width="6" height="6" xoffset="1" yoffset="4" xadvance="9" />
+    <char id="177" x="720" y="18" width="12" height="14" xoffset="1" yoffset="7" xadvance="13" />
+    <char id="178" x="16" y="41" width="7" height="8" xoffset="0" yoffset="4" xadvance="8" />
+    <char id="179" x="0" y="41" width="7" height="8" xoffset="0" yoffset="4" xadvance="8" />
+    <char id="180" x="101" y="41" width="4" height="3" xoffset="3" yoffset="4" xadvance="8" />
+    <char id="181" x="603" y="0" width="10" height="18" xoffset="1" yoffset="8" xadvance="12" />
+    <char id="182" x="378" y="0" width="12" height="21" xoffset="0" yoffset="4" xadvance="12" />
+    <char id="183" x="164" y="40" width="2" height="2" xoffset="3" yoffset="12" xadvance="8" />
+    <char id="184" x="95" y="41" width="5" height="4" xoffset="1" yoffset="21" xadvance="8" />
+    <char id="185" x="1017" y="18" width="5" height="8" xoffset="1" yoffset="4" xadvance="8" />
+    <char id="186" x="24" y="41" width="7" height="8" xoffset="1" yoffset="4" xadvance="9" />
+    <char id="187" x="963" y="18" width="9" height="10" xoffset="3" yoffset="10" xadvance="13" />
+    <char id="188" x="705" y="0" width="18" height="17" xoffset="1" yoffset="4" xadvance="19" />
+    <char id="189" x="780" y="0" width="17" height="17" xoffset="1" yoffset="4" xadvance="19" />
+    <char id="190" x="743" y="0" width="18" height="17" xoffset="0" yoffset="4" xadvance="19" />
+    <char id="191" x="625" y="0" width="10" height="18" xoffset="2" yoffset="8" xadvance="14" />
+    <char id="192" x="137" y="0" width="17" height="21" xoffset="-1" yoffset="0" xadvance="15" />
+    <char id="193" x="173" y="0" width="17" height="21" xoffset="-1" yoffset="0" xadvance="15" />
+    <char id="194" x="191" y="0" width="17" height="21" xoffset="-1" yoffset="0" xadvance="15" />
+    <char id="195" x="155" y="0" width="17" height="21" xoffset="-1" yoffset="0" xadvance="15" />
+    <char id="196" x="449" y="0" width="17" height="20" xoffset="-1" yoffset="1" xadvance="15" />
+    <char id="197" x="119" y="0" width="17" height="21" xoffset="-1" yoffset="0" xadvance="15" />
+    <char id="198" x="681" y="0" width="23" height="17" xoffset="-1" yoffset="4" xadvance="23" />
+    <char id="199" x="277" y="0" width="15" height="21" xoffset="1" yoffset="4" xadvance="17" />
+    <char id="200" x="404" y="0" width="12" height="21" xoffset="2" yoffset="0" xadvance="15" />
+    <char id="201" x="391" y="0" width="12" height="21" xoffset="2" yoffset="0" xadvance="15" />
+    <char id="202" x="417" y="0" width="12" height="21" xoffset="2" yoffset="0" xadvance="15" />
+    <char id="203" x="498" y="0" width="12" height="20" xoffset="2" yoffset="1" xadvance="15" />
+    <char id="204" x="444" y="0" width="4" height="21" xoffset="1" yoffset="0" xadvance="6" />
+    <char id="205" x="439" y="0" width="4" height="21" xoffset="1" yoffset="0" xadvance="6" />
+    <char id="206" x="430" y="0" width="8" height="21" xoffset="-1" yoffset="0" xadvance="6" />
+    <char id="207" x="523" y="0" width="6" height="20" xoffset="0" yoffset="1" xadvance="6" />
+    <char id="208" x="886" y="0" width="16" height="17" xoffset="0" yoffset="4" xadvance="17" />
+    <char id="209" x="364" y="0" width="13" height="21" xoffset="2" yoffset="0" xadvance="17" />
+    <char id="210" x="209" y="0" width="16" height="21" xoffset="1" yoffset="0" xadvance="18" />
+    <char id="211" x="260" y="0" width="16" height="21" xoffset="1" yoffset="0" xadvance="18" />
+    <char id="212" x="243" y="0" width="16" height="21" xoffset="1" yoffset="0" xadvance="18" />
+    <char id="213" x="226" y="0" width="16" height="21" xoffset="1" yoffset="0" xadvance="18" />
+    <char id="214" x="467" y="0" width="16" height="20" xoffset="1" yoffset="1" xadvance="18" />
+    <char id="215" x="994" y="18" width="9" height="9" xoffset="2" yoffset="8" xadvance="13" />
+    <char id="216" x="542" y="0" width="17" height="18" xoffset="1" yoffset="4" xadvance="18" />
+    <char id="217" x="350" y="0" width="13" height="21" xoffset="2" yoffset="0" xadvance="17" />
+    <char id="218" x="336" y="0" width="13" height="21" xoffset="2" yoffset="0" xadvance="17" />
+    <char id="219" x="322" y="0" width="13" height="21" xoffset="2" yoffset="0" xadvance="17" />
+    <char id="220" x="484" y="0" width="13" height="20" xoffset="2" yoffset="1" xadvance="17" />
+    <char id="221" x="293" y="0" width="14" height="21" xoffset="0" yoffset="0" xadvance="15" />
+    <char id="222" x="137" y="22" width="12" height="17" xoffset="2" yoffset="4" xadvance="15" />
+    <char id="223" x="150" y="22" width="12" height="17" xoffset="2" yoffset="4" xadvance="14" />
+    <char id="224" x="297" y="22" width="11" height="17" xoffset="1" yoffset="4" xadvance="13" />
+    <char id="225" x="309" y="22" width="11" height="17" xoffset="1" yoffset="4" xadvance="13" />
+    <char id="226" x="321" y="22" width="11" height="17" xoffset="1" yoffset="4" xadvance="13" />
+    <char id="227" x="333" y="22" width="11" height="17" xoffset="1" yoffset="4" xadvance="13" />
+    <char id="228" x="675" y="18" width="11" height="16" xoffset="1" yoffset="5" xadvance="13" />
+    <char id="229" x="530" y="0" width="11" height="19" xoffset="1" yoffset="2" xadvance="13" />
+    <char id="230" x="733" y="18" width="19" height="13" xoffset="1" yoffset="8" xadvance="20" />
+    <char id="231" x="488" y="21" width="10" height="17" xoffset="1" yoffset="8" xadvance="12" />
+    <char id="232" x="465" y="21" width="11" height="17" xoffset="1" yoffset="4" xadvance="13" />
+    <char id="233" x="357" y="22" width="11" height="17" xoffset="1" yoffset="4" xadvance="13" />
+    <char id="234" x="369" y="22" width="11" height="17" xoffset="1" yoffset="4" xadvance="13" />
+    <char id="235" x="663" y="18" width="11" height="16" xoffset="1" yoffset="5" xadvance="13" />
+    <char id="236" x="627" y="19" width="4" height="17" xoffset="1" yoffset="4" xadvance="6" />
+    <char id="237" x="632" y="19" width="4" height="17" xoffset="1" yoffset="4" xadvance="6" />
+    <char id="238" x="586" y="19" width="8" height="17" xoffset="-1" yoffset="4" xadvance="6" />
+    <char id="239" x="710" y="18" width="6" height="16" xoffset="0" yoffset="5" xadvance="6" />
+    <char id="240" x="381" y="22" width="11" height="17" xoffset="1" yoffset="4" xadvance="13" />
+    <char id="241" x="510" y="21" width="10" height="17" xoffset="1" yoffset="4" xadvance="13" />
+    <char id="242" x="393" y="22" width="11" height="17" xoffset="1" yoffset="4" xadvance="13" />
+    <char id="243" x="405" y="22" width="11" height="17" xoffset="1" yoffset="4" xadvance="13" />
+    <char id="244" x="417" y="22" width="11" height="17" xoffset="1" yoffset="4" xadvance="13" />
+    <char id="245" x="429" y="22" width="11" height="17" xoffset="1" yoffset="4" xadvance="13" />
+    <char id="246" x="687" y="18" width="11" height="16" xoffset="1" yoffset="5" xadvance="13" />
+    <char id="247" x="1004" y="18" width="12" height="8" xoffset="1" yoffset="9" xadvance="13" />
+    <char id="248" x="649" y="19" width="13" height="16" xoffset="0" yoffset="6" xadvance="13" />
+    <char id="249" x="532" y="20" width="10" height="17" xoffset="1" yoffset="4" xadvance="13" />
+    <char id="250" x="521" y="21" width="10" height="17" xoffset="1" yoffset="4" xadvance="13" />
+    <char id="251" x="499" y="21" width="10" height="17" xoffset="1" yoffset="4" xadvance="13" />
+    <char id="252" x="699" y="18" width="10" height="16" xoffset="1" yoffset="5" xadvance="13" />
+    <char id="253" x="22" y="0" width="13" height="22" xoffset="-1" yoffset="4" xadvance="12" />
+    <char id="254" x="36" y="0" width="11" height="22" xoffset="1" yoffset="4" xadvance="13" />
+    <char id="255" x="308" y="0" width="13" height="21" xoffset="-1" yoffset="5" xadvance="12" />
+  </chars>
+  <kernings count="70">
+    <kerning first="32" second="65" amount="-1" />
+    <kerning first="49" second="49" amount="-2" />
+    <kerning first="65" second="32" amount="-1" />
+    <kerning first="65" second="84" amount="-2" />
+    <kerning first="65" second="86" amount="-2" />
+    <kerning first="65" second="87" amount="-1" />
+    <kerning first="65" second="89" amount="-2" />
+    <kerning first="70" second="44" amount="-3" />
+    <kerning first="70" second="46" amount="-3" />
+    <kerning first="70" second="65" amount="-1" />
+    <kerning first="76" second="32" amount="-1" />
+    <kerning first="76" second="84" amount="-2" />
+    <kerning first="76" second="86" amount="-2" />
+    <kerning first="76" second="87" amount="-2" />
+    <kerning first="76" second="89" amount="-2" />
+    <kerning first="76" second="121" amount="-1" />
+    <kerning first="80" second="44" amount="-3" />
+    <kerning first="80" second="46" amount="-3" />
+    <kerning first="80" second="65" amount="-2" />
+    <kerning first="84" second="44" amount="-3" />
+    <kerning first="84" second="45" amount="-1" />
+    <kerning first="84" second="46" amount="-3" />
+    <kerning first="84" second="58" amount="-3" />
+    <kerning first="84" second="65" amount="-2" />
+    <kerning first="84" second="97" amount="-3" />
+    <kerning first="84" second="99" amount="-3" />
+    <kerning first="84" second="101" amount="-3" />
+    <kerning first="84" second="105" amount="-1" />
+    <kerning first="84" second="111" amount="-3" />
+    <kerning first="84" second="114" amount="-1" />
+    <kerning first="84" second="115" amount="-3" />
+    <kerning first="84" second="117" amount="-1" />
+    <kerning first="84" second="119" amount="-1" />
+    <kerning first="84" second="121" amount="-1" />
+    <kerning first="86" second="44" amount="-2" />
+    <kerning first="86" second="45" amount="-1" />
+    <kerning first="86" second="46" amount="-2" />
+    <kerning first="86" second="58" amount="-1" />
+    <kerning first="86" second="65" amount="-2" />
+    <kerning first="86" second="97" amount="-2" />
+    <kerning first="86" second="101" amount="-1" />
+    <kerning first="86" second="111" amount="-1" />
+    <kerning first="86" second="114" amount="-1" />
+    <kerning first="86" second="117" amount="-1" />
+    <kerning first="86" second="121" amount="-1" />
+    <kerning first="87" second="44" amount="-1" />
+    <kerning first="87" second="46" amount="-1" />
+    <kerning first="87" second="65" amount="-1" />
+    <kerning first="87" second="97" amount="-1" />
+    <kerning first="89" second="44" amount="-3" />
+    <kerning first="89" second="45" amount="-2" />
+    <kerning first="89" second="46" amount="-3" />
+    <kerning first="89" second="58" amount="-1" />
+    <kerning first="89" second="65" amount="-2" />
+    <kerning first="89" second="97" amount="-2" />
+    <kerning first="89" second="101" amount="-2" />
+    <kerning first="89" second="105" amount="-1" />
+    <kerning first="89" second="111" amount="-2" />
+    <kerning first="89" second="112" amount="-2" />
+    <kerning first="89" second="113" amount="-2" />
+    <kerning first="89" second="117" amount="-1" />
+    <kerning first="89" second="118" amount="-1" />
+    <kerning first="114" second="44" amount="-1" />
+    <kerning first="114" second="46" amount="-1" />
+    <kerning first="118" second="44" amount="-2" />
+    <kerning first="118" second="46" amount="-2" />
+    <kerning first="119" second="44" amount="-1" />
+    <kerning first="119" second="46" amount="-1" />
+    <kerning first="121" second="44" amount="-2" />
+    <kerning first="121" second="46" amount="-2" />
+  </kernings>
+</font>

BIN
Samples/assets/Arial_0.tga


+ 28 - 0
Samples/assets/bitmapfont.rml

@@ -0,0 +1,28 @@
+<rml>
+	<head>
+		<title>Demo</title>
+		<link type="text/template" href="window.rml" />
+		<style>
+			body
+			{
+				width: 300px;
+				height: 225px;
+				font-family: Arial;
+				margin: auto;
+			}
+			
+			div#title_bar div#icon
+			{
+				display: none;
+			}
+			
+			div#content
+			{
+				text-align: left;
+			}
+		</style>
+	</head>
+	<body template="window">
+		This is a bitmap font<br/>sample.
+	</body>
+</rml>

+ 130 - 0
Samples/basic/bitmapfont/src/main.cpp

@@ -0,0 +1,130 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * 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.
+ *
+ */
+
+#include <Rocket/Core.h>
+#include <Rocket/Debugger.h>
+#include <Input.h>
+#include <Shell.h>
+
+Rocket::Core::Context* context = NULL;
+
+ShellRenderInterfaceExtensions *shell_renderer;
+
+void GameLoop()
+{
+	context->Update();
+
+	shell_renderer->PrepareRenderBuffer();
+	context->Render();
+	shell_renderer->PresentRenderBuffer();
+}
+
+#if defined ROCKET_PLATFORM_WIN32
+#include <windows.h>
+int APIENTRY WinMain(HINSTANCE ROCKET_UNUSED_PARAMETER(instance_handle), HINSTANCE ROCKET_UNUSED_PARAMETER(previous_instance_handle), char* ROCKET_UNUSED_PARAMETER(command_line), int ROCKET_UNUSED_PARAMETER(command_show))
+#else
+int main(int ROCKET_UNUSED_PARAMETER(argc), char** ROCKET_UNUSED_PARAMETER(argv))
+#endif
+{
+#ifdef ROCKET_PLATFORM_WIN32
+	ROCKET_UNUSED(instance_handle);
+	ROCKET_UNUSED(previous_instance_handle);
+	ROCKET_UNUSED(command_line);
+	ROCKET_UNUSED(command_show);
+#else
+	ROCKET_UNUSED(argc);
+	ROCKET_UNUSED(argv);
+#endif
+
+#ifdef ROCKET_PLATFORM_LINUX
+#define APP_PATH "../Samples/basic/loaddocument/"
+#else
+#define APP_PATH "../../Samples/basic/loaddocument/"
+#endif
+
+#ifdef ROCKET_PLATFORM_WIN32
+        DoAllocConsole();
+#endif
+
+        int window_width = 1024;
+        int window_height = 768;
+
+	ShellRenderInterfaceOpenGL opengl_renderer;
+	shell_renderer = &opengl_renderer;
+
+	// Generic OS initialisation, creates a window and attaches OpenGL.
+	if (!Shell::Initialise(APP_PATH) ||
+		!Shell::OpenWindow("Load Document Sample", shell_renderer, window_width, window_height, true))
+	{
+		Shell::Shutdown();
+		return -1;
+	}
+
+	// Rocket initialisation.
+	Rocket::Core::SetRenderInterface(&opengl_renderer);
+	shell_renderer->SetViewport(window_width, window_height);
+
+	ShellSystemInterface system_interface;
+	Rocket::Core::SetSystemInterface(&system_interface);
+
+	Rocket::Core::Initialise();
+
+	// Create the main Rocket context and set it on the shell's input layer.
+	context = Rocket::Core::CreateContext("main", Rocket::Core::Vector2i(window_width, window_height));
+	if (context == NULL)
+	{
+		Rocket::Core::Shutdown();
+		Shell::Shutdown();
+		return -1;
+	}
+
+	Rocket::Debugger::Initialise(context);
+	Input::SetContext(context);
+	shell_renderer->SetContext(context);
+
+    // Load bitmap font
+    Rocket::Core::FontDatabase::LoadFontFace("../../assets/Arial.fnt");
+	
+    // Load and show the demo document.
+	Rocket::Core::ElementDocument* document = context->LoadDocument("../../assets/bitmapfont.rml");
+	if (document != NULL)
+	{
+		document->Show();
+		document->RemoveReference();
+	}
+
+	Shell::EventLoop(GameLoop);
+
+	// Shutdown Rocket.
+	context->RemoveReference();
+	Rocket::Core::Shutdown();
+
+	Shell::CloseWindow();
+	Shell::Shutdown();
+
+	return 0;
+}

+ 12 - 0
Samples/basic/sdl2/src/main.cpp

@@ -154,8 +154,20 @@ int main(int argc, char **argv)
                     break;
                     break;
 
 
                 case SDL_KEYDOWN:
                 case SDL_KEYDOWN:
+                {
+                    // Intercept SHIFT + ~ key stroke to toggle libRocket's 
+                    // visual debugger tool
+                    if( event.key.keysym.sym == SDLK_BACKQUOTE && 
+                        event.key.keysym.mod == KMOD_LSHIFT )
+                    {
+                        Rocket::Debugger::SetVisible( ! Rocket::Debugger::IsVisible() );
+                        break;
+                    }
+                    
                     Context->ProcessKeyDown(SystemInterface.TranslateKey(event.key.keysym.sym), SystemInterface.GetKeyModifiers());
                     Context->ProcessKeyDown(SystemInterface.TranslateKey(event.key.keysym.sym), SystemInterface.GetKeyModifiers());
                     break;
                     break;
+                }
+                
                 default:
                 default:
                     break;
                     break;
             }
             }

+ 1 - 1
Samples/luainvaders/src/LuaInterface.cpp

@@ -84,7 +84,7 @@ int GameSetPaused(lua_State* L)
 
 
 int GameSetDifficulty(lua_State* L)
 int GameSetDifficulty(lua_State* L)
 {
 {
-    int difficulty = luaL_checkint(L,1);
+    int difficulty = luaL_checkinteger(L,1);
     GameDetails::SetDifficulty((GameDetails::Difficulty)difficulty);
     GameDetails::SetDifficulty((GameDetails::Difficulty)difficulty);
     return 0;
     return 0;
 }
 }

+ 1 - 0
Samples/pyinvaders/src/main.cpp

@@ -74,6 +74,7 @@ int main(int ROCKET_UNUSED_PARAMETER(argc), char** ROCKET_UNUSED_PARAMETER(argv)
 // @TODO Make these lookup at runtime rather than using hard coded paths
 // @TODO Make these lookup at runtime rather than using hard coded paths
 #ifdef ROCKET_PLATFORM_LINUX
 #ifdef ROCKET_PLATFORM_LINUX
 #define APP_PATH "../Samples/pyinvaders/"
 #define APP_PATH "../Samples/pyinvaders/"
+#define ROCKET_PATH ""
 #else
 #else
 #define APP_PATH "../../Samples/pyinvaders/"
 #define APP_PATH "../../Samples/pyinvaders/"
 #define ROCKET_PATH "."
 #define ROCKET_PATH "."

+ 3 - 1
Samples/shell/src/macosx/ShellRenderInterfaceExtensionsOpenGL_MacOSX.cpp

@@ -99,7 +99,9 @@ bool ShellRenderInterfaceOpenGL::AttachToNative(void *nativeWindow)
 	
 	
 	glMatrixMode(GL_PROJECTION);
 	glMatrixMode(GL_PROJECTION);
 	glLoadIdentity();
 	glLoadIdentity();
-	glOrtho(0, 1024, 768, 0, -1, 1);
+	Rect crect;
+	GetWindowBounds(window, kWindowContentRgn, &crect);
+	glOrtho(0, (crect.right - crect.left), (crect.bottom - crect.top), 0, -1, 1);
 	
 	
 	glMatrixMode(GL_MODELVIEW);
 	glMatrixMode(GL_MODELVIEW);
 	glLoadIdentity();
 	glLoadIdentity();

+ 1 - 1
Source/Controls/ElementDataGridRow.cpp

@@ -249,7 +249,7 @@ ElementDataGrid* ElementDataGridRow::GetParentGrid()
 	return parent_grid;
 	return parent_grid;
 }
 }
 
 
-void ElementDataGridRow::OnDataSourceDestroy(DataSource* data_source)
+void ElementDataGridRow::OnDataSourceDestroy(DataSource* ROCKET_UNUSED_PARAMETER(_data_source))
 {
 {
 	if(data_source != NULL)
 	if(data_source != NULL)
 	{
 	{

+ 6 - 6
Source/Controls/Lua/DataSource.cpp

@@ -48,8 +48,8 @@ int DataSourceNotifyRowAdd(lua_State* L, DataSource* obj)
 {
 {
     LUACHECKOBJ(obj);
     LUACHECKOBJ(obj);
     const char* table_name = luaL_checkstring(L,1);
     const char* table_name = luaL_checkstring(L,1);
-    int first_row_added = luaL_checkint(L,2);
-    int num_rows_added = luaL_checkint(L,3);
+    int first_row_added = luaL_checkinteger(L,2);
+    int num_rows_added = luaL_checkinteger(L,3);
     obj->NotifyRowAdd(table_name,first_row_added,num_rows_added);
     obj->NotifyRowAdd(table_name,first_row_added,num_rows_added);
     return 0;
     return 0;
 }
 }
@@ -58,8 +58,8 @@ int DataSourceNotifyRowRemove(lua_State* L, DataSource* obj)
 {
 {
     LUACHECKOBJ(obj);
     LUACHECKOBJ(obj);
     const char* table_name = luaL_checkstring(L,1);
     const char* table_name = luaL_checkstring(L,1);
-    int first_row_removed = luaL_checkint(L,2);
-    int num_rows_removed = luaL_checkint(L,3);
+    int first_row_removed = luaL_checkinteger(L,2);
+    int num_rows_removed = luaL_checkinteger(L,3);
     obj->NotifyRowRemove(table_name,first_row_removed,num_rows_removed);
     obj->NotifyRowRemove(table_name,first_row_removed,num_rows_removed);
     return 0;
     return 0;
 }
 }
@@ -74,8 +74,8 @@ int DataSourceNotifyRowChange(lua_State* L, DataSource* obj)
     }
     }
     else
     else
     {
     {
-        int first_row_changed = luaL_checkint(L,2);
-        int num_rows_changed = luaL_checkint(L,3);
+        int first_row_changed = luaL_checkinteger(L,2);
+        int num_rows_changed = luaL_checkinteger(L,3);
         obj->NotifyRowChange(table_name,first_row_changed,num_rows_changed);
         obj->NotifyRowChange(table_name,first_row_changed,num_rows_changed);
     }
     }
     return 0;
     return 0;

+ 5 - 5
Source/Controls/Lua/ElementFormControlInput.cpp

@@ -103,7 +103,7 @@ int ElementFormControlInputSetAttrmaxlength(lua_State* L)
 {
 {
     ElementFormControlInput* obj = LuaType<ElementFormControlInput>::check(L,1);
     ElementFormControlInput* obj = LuaType<ElementFormControlInput>::check(L,1);
     LUACHECKOBJ(obj);
     LUACHECKOBJ(obj);
-    int maxlength = luaL_checkint(L,2);
+    int maxlength = luaL_checkinteger(L,2);
     obj->SetAttribute("maxlength",maxlength);
     obj->SetAttribute("maxlength",maxlength);
     return 0;
     return 0;
 }
 }
@@ -112,7 +112,7 @@ int ElementFormControlInputSetAttrsize(lua_State* L)
 {
 {
     ElementFormControlInput* obj = LuaType<ElementFormControlInput>::check(L,1);
     ElementFormControlInput* obj = LuaType<ElementFormControlInput>::check(L,1);
     LUACHECKOBJ(obj);
     LUACHECKOBJ(obj);
-    int size = luaL_checkint(L,2);
+    int size = luaL_checkinteger(L,2);
     obj->SetAttribute("size",size);
     obj->SetAttribute("size",size);
     return 0;
     return 0;
 }
 }
@@ -121,7 +121,7 @@ int ElementFormControlInputSetAttrmax(lua_State* L)
 {
 {
     ElementFormControlInput* obj = LuaType<ElementFormControlInput>::check(L,1);
     ElementFormControlInput* obj = LuaType<ElementFormControlInput>::check(L,1);
     LUACHECKOBJ(obj);
     LUACHECKOBJ(obj);
-    int max = luaL_checkint(L,2);
+    int max = luaL_checkinteger(L,2);
     obj->SetAttribute("max",max);
     obj->SetAttribute("max",max);
     return 0;
     return 0;
 }
 }
@@ -130,7 +130,7 @@ int ElementFormControlInputSetAttrmin(lua_State* L)
 {
 {
     ElementFormControlInput* obj = LuaType<ElementFormControlInput>::check(L,1);
     ElementFormControlInput* obj = LuaType<ElementFormControlInput>::check(L,1);
     LUACHECKOBJ(obj);
     LUACHECKOBJ(obj);
-    int min = luaL_checkint(L,2);
+    int min = luaL_checkinteger(L,2);
     obj->SetAttribute("min",min);
     obj->SetAttribute("min",min);
     return 0;
     return 0;
 }
 }
@@ -139,7 +139,7 @@ int ElementFormControlInputSetAttrstep(lua_State* L)
 {
 {
     ElementFormControlInput* obj = LuaType<ElementFormControlInput>::check(L,1);
     ElementFormControlInput* obj = LuaType<ElementFormControlInput>::check(L,1);
     LUACHECKOBJ(obj);
     LUACHECKOBJ(obj);
-    int step = luaL_checkint(L,2);
+    int step = luaL_checkinteger(L,2);
     obj->SetAttribute("step",step);
     obj->SetAttribute("step",step);
     return 0;
     return 0;
 }
 }

+ 3 - 3
Source/Controls/Lua/ElementFormControlSelect.cpp

@@ -46,7 +46,7 @@ int ElementFormControlSelectAdd(lua_State* L, ElementFormControlSelect* obj)
     const char* value = luaL_checkstring(L,2);
     const char* value = luaL_checkstring(L,2);
     int before = -1; //default
     int before = -1; //default
     if(lua_gettop(L) >= 3)
     if(lua_gettop(L) >= 3)
-        before = luaL_checkint(L,3);
+        before = luaL_checkinteger(L,3);
 
 
     int index = obj->Add(rml,value,before);
     int index = obj->Add(rml,value,before);
     lua_pushinteger(L,index);
     lua_pushinteger(L,index);
@@ -55,7 +55,7 @@ int ElementFormControlSelectAdd(lua_State* L, ElementFormControlSelect* obj)
 
 
 int ElementFormControlSelectRemove(lua_State* L, ElementFormControlSelect* obj)
 int ElementFormControlSelectRemove(lua_State* L, ElementFormControlSelect* obj)
 {
 {
-    int index = luaL_checkint(L,1);
+    int index = luaL_checkinteger(L,1);
     obj->Remove(index);
     obj->Remove(index);
     return 0;
     return 0;
 }
 }
@@ -86,7 +86,7 @@ int ElementFormControlSelectSetAttrselection(lua_State* L)
 {
 {
     ElementFormControlSelect* obj = LuaType<ElementFormControlSelect>::check(L,1);
     ElementFormControlSelect* obj = LuaType<ElementFormControlSelect>::check(L,1);
     LUACHECKOBJ(obj);
     LUACHECKOBJ(obj);
-    int selection = luaL_checkint(L,2);
+    int selection = luaL_checkinteger(L,2);
     obj->SetSelection(selection);
     obj->SetSelection(selection);
     return 0;
     return 0;
 }
 }

+ 3 - 3
Source/Controls/Lua/ElementFormControlTextArea.cpp

@@ -74,7 +74,7 @@ int ElementFormControlTextAreaSetAttrcols(lua_State* L)
 {
 {
     ElementFormControlTextArea* obj = LuaType<ElementFormControlTextArea>::check(L,1);
     ElementFormControlTextArea* obj = LuaType<ElementFormControlTextArea>::check(L,1);
     LUACHECKOBJ(obj);
     LUACHECKOBJ(obj);
-    int cols = luaL_checkint(L,2);
+    int cols = luaL_checkinteger(L,2);
     obj->SetNumColumns(cols);
     obj->SetNumColumns(cols);
     return 0;
     return 0;
 }
 }
@@ -83,7 +83,7 @@ int ElementFormControlTextAreaSetAttrmaxlength(lua_State* L)
 {
 {
     ElementFormControlTextArea* obj = LuaType<ElementFormControlTextArea>::check(L,1);
     ElementFormControlTextArea* obj = LuaType<ElementFormControlTextArea>::check(L,1);
     LUACHECKOBJ(obj);
     LUACHECKOBJ(obj);
-    int ml = luaL_checkint(L,2);
+    int ml = luaL_checkinteger(L,2);
     obj->SetMaxLength(ml);
     obj->SetMaxLength(ml);
     return 0;
     return 0;
 }
 }
@@ -92,7 +92,7 @@ int ElementFormControlTextAreaSetAttrrows(lua_State* L)
 {
 {
     ElementFormControlTextArea* obj = LuaType<ElementFormControlTextArea>::check(L,1);
     ElementFormControlTextArea* obj = LuaType<ElementFormControlTextArea>::check(L,1);
     LUACHECKOBJ(obj);
     LUACHECKOBJ(obj);
-    int rows = luaL_checkint(L,2);
+    int rows = luaL_checkinteger(L,2);
     obj->SetNumRows(rows);
     obj->SetNumRows(rows);
     return 0;
     return 0;
 }
 }

+ 3 - 3
Source/Controls/Lua/ElementTabSet.cpp

@@ -39,7 +39,7 @@ namespace Lua {
 int ElementTabSetSetPanel(lua_State* L, ElementTabSet* obj)
 int ElementTabSetSetPanel(lua_State* L, ElementTabSet* obj)
 {
 {
     LUACHECKOBJ(obj);
     LUACHECKOBJ(obj);
-    int index = luaL_checkint(L,1);
+    int index = luaL_checkinteger(L,1);
     const char* rml = luaL_checkstring(L,2);
     const char* rml = luaL_checkstring(L,2);
 
 
     obj->SetPanel(index,rml);
     obj->SetPanel(index,rml);
@@ -49,7 +49,7 @@ int ElementTabSetSetPanel(lua_State* L, ElementTabSet* obj)
 int ElementTabSetSetTab(lua_State* L, ElementTabSet* obj)
 int ElementTabSetSetTab(lua_State* L, ElementTabSet* obj)
 {
 {
     LUACHECKOBJ(obj);
     LUACHECKOBJ(obj);
-    int index = luaL_checkint(L,1);
+    int index = luaL_checkinteger(L,1);
     const char* rml = luaL_checkstring(L,2);
     const char* rml = luaL_checkstring(L,2);
 
 
     obj->SetTab(index,rml);
     obj->SetTab(index,rml);
@@ -82,7 +82,7 @@ int ElementTabSetSetAttractive_tab(lua_State* L)
 {
 {
     ElementTabSet* obj = LuaType<ElementTabSet>::check(L,1);
     ElementTabSet* obj = LuaType<ElementTabSet>::check(L,1);
     LUACHECKOBJ(obj);
     LUACHECKOBJ(obj);
-    int tab = luaL_checkint(L,2);
+    int tab = luaL_checkinteger(L,2);
     obj->SetActiveTab(tab);
     obj->SetActiveTab(tab);
     return 0;
     return 0;
 }
 }

+ 1 - 1
Source/Controls/Lua/LuaDataSource.cpp

@@ -98,7 +98,7 @@ int LuaDataSource::GetNumRows(const Rocket::Core::String& table)
     int res = lua_gettop(L);
     int res = lua_gettop(L);
     if(lua_type(L,res) == LUA_TNUMBER)
     if(lua_type(L,res) == LUA_TNUMBER)
     {
     {
-        return luaL_checkint(L,res);
+        return luaL_checkinteger(L,res);
     }
     }
     else
     else
     {
     {

+ 1 - 1
Source/Controls/Lua/SelectOptionsProxy.cpp

@@ -43,7 +43,7 @@ int SelectOptionsProxy__index(lua_State* L)
     {
     {
         SelectOptionsProxy* proxy = LuaType<SelectOptionsProxy>::check(L,1);
         SelectOptionsProxy* proxy = LuaType<SelectOptionsProxy>::check(L,1);
         LUACHECKOBJ(proxy);
         LUACHECKOBJ(proxy);
-        int index = luaL_checkint(L,2);
+        int index = luaL_checkinteger(L,2);
         Rocket::Controls::SelectOption* opt = proxy->owner->GetOption(index);
         Rocket::Controls::SelectOption* opt = proxy->owner->GetOption(index);
         LUACHECKOBJ(opt);
         LUACHECKOBJ(opt);
         lua_newtable(L);
         lua_newtable(L);

+ 147 - 0
Source/Core/BitmapFont/BitmapFontDefinitions.h

@@ -0,0 +1,147 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * 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 BITMAPFONTDEFINITIONS_H
+#define BITMAPFONTDEFINITIONS_H
+
+#include <Rocket/Core/Header.h>
+#include <Rocket/Core/Types.h>
+#include <Rocket/Core/Dictionary.h>
+#include <set>
+
+namespace Rocket {
+namespace Core {
+namespace BitmapFont {
+
+	struct FontInfo
+	{
+		String FamilyName;
+		String Source;
+		String BitmapSource;
+		int Size;
+		Font::Style Style;
+		Font::Weight Weight;
+	};
+
+	struct CharacterCommonInfo
+	{
+		int LineHeight;
+		int BaseLine;
+		int ScaleWidth;
+		int ScaleHeight;
+		int CharacterCount;
+		int KerningCount;
+	};
+
+	struct CharacterInfo
+	{
+		int Id;
+		int X;
+		int Y;
+		int Width;
+		int Height;
+		int XOffset;
+		int YOffset;
+		int Advance;
+	};
+
+	struct KerningInfo
+	{
+		int FirstCharacterId;
+		int SecondCharacterId;
+		int KerningAmount;
+	};
+
+	class BitmapFontDefinitions
+	{
+	public:
+		FontInfo Face;
+		CharacterCommonInfo CommonCharactersInfo;
+		CharacterInfo *CharactersInfo;
+		KerningInfo *KerningsInfo;
+
+		int BM_Helper_GetCharacterTableIndex( int unicode_code )
+		{
+			return BinarySearch( unicode_code, 0, CommonCharactersInfo.CharacterCount );
+		}
+
+		int BM_Helper_GetXKerning( int left_uni_id, int right_uni_id )
+		{
+			for ( int i = 0; i < this->CommonCharactersInfo.KerningCount; i++ )
+			{
+				if ( this->KerningsInfo[i].FirstCharacterId == left_uni_id && this->KerningsInfo[i].SecondCharacterId == right_uni_id )
+				{
+					return this->KerningsInfo[i].KerningAmount;
+				}
+			}
+
+			return 0;
+		}
+
+	private:
+
+		int BinarySearch( int unicode_code, int min_index, int max_index )
+		{
+			if ( abs( max_index - min_index ) <= 1 )
+			{
+				if ( this->CharactersInfo[ min_index ].Id == unicode_code )
+				{
+					return min_index;
+				}
+				else if ( this->CharactersInfo[ max_index ].Id == unicode_code )
+				{
+					return max_index;
+				}
+				else
+				{
+					return -1;
+				}
+			}
+			else
+			{
+				int mid_index = ( min_index + max_index ) / 2;
+
+				if ( this->CharactersInfo[ mid_index ].Id == unicode_code )
+				{
+					return mid_index;
+				}
+				else if ( this->CharactersInfo[ mid_index ].Id > unicode_code )
+				{
+					return BinarySearch( unicode_code, min_index, mid_index );
+				}
+				else
+				{
+					return BinarySearch( unicode_code, mid_index, max_index );
+				}
+			}
+		}
+	};
+
+}
+}
+}
+#endif

+ 130 - 0
Source/Core/BitmapFont/FontFace.cpp

@@ -0,0 +1,130 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * 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.
+ *
+ */
+
+#include "../precompiled.h"
+#include "FontFace.h"
+#include "FontFaceHandle.h"
+#include <Rocket/Core/Log.h>
+
+namespace Rocket {
+namespace Core {
+namespace BitmapFont {
+
+FontFace::FontFace(BitmapFontDefinitions *_face, Font::Style _style, Font::Weight _weight, bool _release_stream) : Rocket::Core::FontFace(_style, _weight, _release_stream)
+{
+	face = _face;
+}
+
+FontFace::~FontFace()
+{
+	ReleaseFace();
+}
+
+// Returns a handle for positioning and rendering this face at the given size.
+Rocket::Core::FontFaceHandle* FontFace::GetHandle(const String& _raw_charset, int size)
+{
+	UnicodeRangeList charset;
+
+	HandleMap::iterator iterator = handles.find(size);
+	if (iterator != handles.end())
+	{
+		const HandleList& handles = (*iterator).second;
+
+		// Check all the handles if their charsets match the requested one exactly (ie, were specified by the same
+		// string).
+		String raw_charset(_raw_charset);
+		for (size_t i = 0; i < handles.size(); ++i)
+		{
+			if (handles[i]->GetRawCharset() == _raw_charset)
+			{
+				handles[i]->AddReference();
+				return (FontFaceHandle*)handles[i];
+			}
+		}
+
+		// Check all the handles if their charsets contain the requested charset.
+		if (!UnicodeRange::BuildList(charset, raw_charset))
+		{
+			Log::Message(Log::LT_ERROR, "Invalid font charset '%s'.", _raw_charset.CString());
+			return NULL;
+		}
+
+		for (size_t i = 0; i < handles.size(); ++i)
+		{
+			bool range_contained = true;
+
+			const UnicodeRangeList& handle_charset = handles[i]->GetCharset();
+			for (size_t j = 0; j < charset.size() && range_contained; ++j)
+			{
+				if (!charset[j].IsContained(handle_charset))
+					range_contained = false;
+			}
+
+			if (range_contained)
+			{
+				handles[i]->AddReference();
+				return (FontFaceHandle*)handles[i];
+			}
+		}
+	}
+
+	// See if this face has been released.
+	if (face == NULL)
+	{
+		Log::Message(Log::LT_WARNING, "Font face has been released, unable to generate new handle.");
+		return NULL;
+	}
+
+	// Construct and initialise the new handle.
+	FontFaceHandle* handle = new FontFaceHandle();
+	if (!handle->Initialise(face, _raw_charset, size))
+	{
+		handle->RemoveReference();
+		return NULL;
+	}
+
+	// Save the handle, and add a reference for the callee. The initial reference will be removed when the font face
+	// releases it.
+	if (iterator != handles.end())
+		(*iterator).second.push_back(handle);
+	else
+		handles[size] = HandleList(1, handle);
+
+	handle->AddReference();
+
+	return handle;
+}
+
+// Releases the face's structure.
+void FontFace::ReleaseFace()
+{
+	delete face;
+}
+
+}
+}
+}

+ 68 - 0
Source/Core/BitmapFont/FontFace.h

@@ -0,0 +1,68 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * 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 ROCKETCOREBITMAPFONTFACE_H
+#define ROCKETCOREBITMAPFONTFACE_H
+
+#include "../../../Include/Rocket/Core/FontFace.h"
+#include "BitmapFontDefinitions.h"
+
+namespace Rocket {
+namespace Core {
+namespace BitmapFont {
+
+class FontFaceHandle;
+
+/**
+	@author Peter Curry
+ */
+
+class FontFace : public Rocket::Core::FontFace
+{
+public:
+	FontFace(BitmapFontDefinitions *_face, Font::Style style, Font::Weight weight, bool release_stream);
+	~FontFace();
+
+	/// Returns a handle for positioning and rendering this face at the given size.
+	/// @param[in] charset The set of characters in the handle, as a comma-separated list of unicode ranges.
+	/// @param[in] size The size of the desired handle, in points.
+	/// @return The shared font handle.
+	Rocket::Core::FontFaceHandle* GetHandle(const String& charset, int size);
+
+	/// Releases the face's FreeType face structure. This will mean handles for new sizes cannot be constructed,
+	/// but existing ones can still be fetched.
+	void ReleaseFace();
+
+private:
+	BitmapFontDefinitions *face;
+};
+
+}
+}
+}
+
+#endif

+ 428 - 0
Source/Core/BitmapFont/FontFaceHandle.cpp

@@ -0,0 +1,428 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * 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.
+ *
+ */
+
+#include "../precompiled.h"
+#include "FontFaceHandle.h"
+#include "FontFaceLayer.h"
+#include <algorithm>
+#include "../TextureLayout.h"
+
+namespace Rocket {
+namespace Core {
+namespace BitmapFont {
+
+class FontEffectSort
+{
+public:
+	bool operator()(const Rocket::Core::FontEffect* lhs, const Rocket::Core::FontEffect* rhs)
+	{
+		return lhs->GetZIndex() < rhs->GetZIndex();
+	}
+};
+
+FontFaceHandle::FontFaceHandle()
+{
+	size = 0;
+	average_advance = 0;
+	x_height = 0;
+	line_height = 0;
+	baseline = 0;
+
+	underline_position = 0;
+	underline_thickness = 0;
+
+	base_layer = NULL;
+}
+
+FontFaceHandle::~FontFaceHandle()
+{
+}
+
+// Initialises the handle so it is able to render text.
+bool FontFaceHandle::Initialise(BitmapFontDefinitions *bm_face, const String& _charset, int _size)
+{
+	this->bm_face = bm_face;
+	size = _size;
+	line_height = _size;
+	texture_width = bm_face->CommonCharactersInfo.ScaleWidth;
+	texture_height = bm_face->CommonCharactersInfo.ScaleHeight;
+	raw_charset = _charset;
+
+	// Construct proper path to texture
+	URL fnt_source = bm_face->Face.Source;
+	URL bitmap_source = bm_face->Face.BitmapSource;
+	if(bitmap_source.GetPath().Empty())
+	{
+		texture_source = fnt_source.GetPath() + bitmap_source.GetFileName();
+		if(!bitmap_source.GetExtension().Empty())
+		{
+			texture_source += "." + bitmap_source.GetExtension();
+		}
+	}
+	else
+	{
+		texture_source = bitmap_source.GetPathedFileName();
+	}
+
+	if (!UnicodeRange::BuildList(charset, raw_charset))
+	{
+		Log::Message(Log::LT_ERROR, "Invalid font charset '%s'.", raw_charset.CString());
+		return false;
+	}
+
+	// Construct the list of the characters specified by the charset.
+	for (size_t i = 0; i < charset.size(); ++i)
+		BuildGlyphMap(bm_face, charset[i]);
+
+	// Generate the metrics for the handle.
+	GenerateMetrics(bm_face);
+
+	// Generate the default layer and layer configuration.
+	base_layer = GenerateLayer(NULL);
+	layer_configurations.push_back(LayerConfiguration());
+	layer_configurations.back().push_back(base_layer);
+
+	return true;
+}
+
+// Returns the width a string will take up if rendered with this handle.
+int FontFaceHandle::GetStringWidth(const WString& string, word prior_character) const
+{
+	int width = 0;
+
+	for (size_t i = 0; i < string.Length(); i++)
+	{
+		word character_code = string[i];
+
+		if (character_code >= glyphs.size())
+			continue;
+		const FontGlyph &glyph = glyphs[character_code];
+
+		// Adjust the cursor for the kerning between this character and the previous one.
+		if (prior_character != 0)
+			width += GetKerning(prior_character, string[i]);
+		// Adjust the cursor for this character's advance.
+		width += glyph.advance;
+
+		prior_character = character_code;
+	}
+
+	return width;
+}
+
+// Generates, if required, the layer configuration for a given array of font effects.
+int FontFaceHandle::GenerateLayerConfiguration(FontEffectMap& font_effects)
+{
+	if (font_effects.empty())
+		return 0;
+
+	// Prepare a list of effects, sorted by z-index.
+	FontEffectList sorted_effects;
+	for (FontEffectMap::const_iterator i = font_effects.begin(); i != font_effects.end(); ++i)
+		sorted_effects.push_back(i->second);
+
+	std::sort(sorted_effects.begin(), sorted_effects.end(), FontEffectSort());
+
+	// Check each existing configuration for a match with this arrangement of effects.
+	int configuration_index = 1;
+	for (; configuration_index < (int) layer_configurations.size(); ++configuration_index)
+	{
+		const LayerConfiguration& configuration = layer_configurations[configuration_index];
+
+		// Check the size is correct. For a math, there should be one layer in the configuration
+		// plus an extra for the base layer.
+		if (configuration.size() != sorted_effects.size() + 1)
+			continue;
+
+		// Check through each layer, checking it was created by the same effect as the one we're
+		// checking.
+		size_t effect_index = 0;
+		for (size_t i = 0; i < configuration.size(); ++i)
+		{
+			// Skip the base layer ...
+			if (configuration[i]->GetFontEffect() == NULL)
+				continue;
+
+			// If the ith layer's effect doesn't match the equivalent effect, then this
+			// configuration can't match.
+			if (configuration[i]->GetFontEffect() != sorted_effects[effect_index])
+				break;
+
+			// Check the next one ...
+			++effect_index;
+		}
+
+		if (effect_index == sorted_effects.size())
+			return configuration_index;
+	}
+
+	// No match, so we have to generate a new layer configuration.
+	layer_configurations.push_back(LayerConfiguration());
+	LayerConfiguration& layer_configuration = layer_configurations.back();
+
+	bool added_base_layer = false;
+
+	for (size_t i = 0; i < sorted_effects.size(); ++i)
+	{
+		if (!added_base_layer &&
+			sorted_effects[i]->GetZIndex() >= 0)
+		{
+			layer_configuration.push_back(base_layer);
+			added_base_layer = true;
+		}
+
+		layer_configuration.push_back(GenerateLayer(sorted_effects[i]));
+	}
+
+	// Add the base layer now if we still haven't added it.
+	if (!added_base_layer)
+		layer_configuration.push_back(base_layer);
+
+	return (int) (layer_configurations.size() - 1);
+}
+
+// Generates the texture data for a layer (for the texture database).
+bool FontFaceHandle::GenerateLayerTexture(const byte*& texture_data, Vector2i& texture_dimensions, Rocket::Core::FontEffect* layer_id, int texture_id)
+{
+	FontLayerMap::iterator layer_iterator = layers.find(layer_id);
+	if (layer_iterator == layers.end())
+		return false;
+
+	return layer_iterator->second->GenerateTexture(texture_data, texture_dimensions, texture_id);
+}
+
+// Generates the geometry required to render a single line of text.
+int FontFaceHandle::GenerateString(GeometryList& geometry, const WString& string, const Vector2f& position, const Colourb& colour, int layer_configuration_index) const
+{
+	int geometry_index = 0;
+	int line_width = 0;
+
+	ROCKET_ASSERT(layer_configuration_index >= 0);
+	ROCKET_ASSERT(layer_configuration_index < (int) layer_configurations.size());
+
+	// Fetch the requested configuration and generate the geometry for each one.
+	const LayerConfiguration& layer_configuration = layer_configurations[layer_configuration_index];
+	for (size_t i = 0; i < layer_configuration.size(); ++i)
+	{
+		Rocket::Core::FontFaceLayer* layer = layer_configuration[i];
+
+		Colourb layer_colour;
+		if (layer == base_layer)
+			layer_colour = colour;
+		else
+			layer_colour = layer->GetColour();
+
+		// Resize the geometry list if required.
+		if ((int) geometry.size() < geometry_index + layer->GetNumTextures())
+			geometry.resize(geometry_index + layer->GetNumTextures());
+
+		// Bind the textures to the geometries.
+		for (int i = 0; i < layer->GetNumTextures(); ++i)
+			geometry[geometry_index + i].SetTexture(layer->GetTexture(i));
+
+		line_width = 0;
+		word prior_character = 0;
+
+		const word* string_iterator = string.CString();
+		const word* string_end = string.CString() + string.Length();
+
+		for (; string_iterator != string_end; string_iterator++)
+		{
+			if (*string_iterator >= glyphs.size())
+				continue;
+			const FontGlyph &glyph = glyphs[*string_iterator];
+
+			// Adjust the cursor for the kerning between this character and the previous one.
+			if (prior_character != 0)
+				line_width += GetKerning(prior_character, *string_iterator);
+
+			layer->GenerateGeometry(&geometry[geometry_index], *string_iterator, Vector2f(position.x + line_width, position.y), layer_colour);
+
+			line_width += glyph.advance;
+			prior_character = *string_iterator;
+		}
+
+		geometry_index += layer->GetNumTextures();
+	}
+
+	// Cull any excess geometry from a previous generation.
+	geometry.resize(geometry_index);
+
+	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, Font::Line height, const Colourb& colour) const
+{
+	std::vector< Vertex >& line_vertices = geometry->GetVertices();
+	std::vector< int >& line_indices = geometry->GetIndices();
+
+	float offset;
+	switch (height)
+	{
+		case Font::UNDERLINE:			offset = -underline_position; break;
+		case Font::OVERLINE:			// where to place? offset = -line_height - underline_position; break;
+		case Font::STRIKE_THROUGH:		// where to place? offset = -line_height * 0.5f; break;
+		default:						return;
+	}
+
+	line_vertices.resize(line_vertices.size() + 4);
+	line_indices.resize(line_indices.size() + 6);
+	GeometryUtilities::GenerateQuad(&line_vertices[0] + (line_vertices.size() - 4), &line_indices[0] + (line_indices.size() - 6), Vector2f(position.x, position.y + offset), Vector2f((float) width, underline_thickness), colour, line_vertices.size() - 4);
+}
+
+// Destroys the handle.
+void FontFaceHandle::OnReferenceDeactivate()
+{
+	delete this;
+}
+
+void FontFaceHandle::GenerateMetrics(BitmapFontDefinitions *bm_face)
+{
+	line_height = bm_face->CommonCharactersInfo.LineHeight;
+	baseline = bm_face->CommonCharactersInfo.BaseLine;
+
+	underline_position = (float)line_height - bm_face->CommonCharactersInfo.BaseLine;
+	baseline += int( underline_position / 1.6f );
+	underline_thickness = 1.0f;
+
+	average_advance = 0;
+	for (FontGlyphList::iterator i = glyphs.begin(); i != glyphs.end(); ++i)
+		average_advance += i->advance;
+
+	// Bring the total advance down to the average advance, but scaled up 10%, just to be on the safe side.
+	average_advance = Math::RealToInteger((float) average_advance / (glyphs.size() * 0.9f));
+
+	// Determine the x-height of this font face.
+	word x = (word) 'x';
+	int index = bm_face->BM_Helper_GetCharacterTableIndex( x );// FT_Get_Char_Index(ft_face, x);
+
+	if ( index >= 0)
+		x_height = bm_face->CharactersInfo[ index ].Height;
+	else
+		x_height = 0;
+}
+
+void FontFaceHandle::BuildGlyphMap(BitmapFontDefinitions *bm_face, const UnicodeRange& unicode_range)
+{
+	glyphs.resize(unicode_range.max_codepoint + 1);
+
+	for (word character_code = (word) (Math::Max< unsigned int >(unicode_range.min_codepoint, 32)); character_code <= unicode_range.max_codepoint; ++character_code)
+	{
+		int index = bm_face->BM_Helper_GetCharacterTableIndex( character_code );
+
+		if ( index < 0 )
+		{
+			continue;
+		}
+
+		FontGlyph glyph;
+		glyph.character = character_code;
+		BuildGlyph(glyph, &bm_face->CharactersInfo[ index ] );
+		glyphs[character_code] = glyph;
+	}
+}
+
+void Rocket::Core::BitmapFont::FontFaceHandle::BuildGlyph(FontGlyph& glyph, CharacterInfo *bm_glyph)
+{
+	// Set the glyph's dimensions.
+	glyph.dimensions.x = bm_glyph->Width;
+	glyph.dimensions.y = bm_glyph->Height;
+
+	// Set the glyph's bearing.
+	glyph.bearing.x = bm_glyph->XOffset;
+	glyph.bearing.y = bm_glyph->YOffset;
+
+	// Set the glyph's advance.
+	glyph.advance = bm_glyph->Advance;
+
+	// Set the glyph's bitmap position.
+	glyph.bitmap_dimensions.x = bm_glyph->X;
+	glyph.bitmap_dimensions.y = bm_glyph->Y;
+
+	glyph.bitmap_data = NULL;
+}
+
+int Rocket::Core::BitmapFont::FontFaceHandle::GetKerning(word lhs, word rhs) const
+{
+	if( bm_face != NULL)
+	{
+		return bm_face->BM_Helper_GetXKerning(lhs, rhs);
+	}
+
+	return 0;
+}
+
+// Generates (or shares) a layer derived from a font effect.
+Rocket::Core::FontFaceLayer* FontFaceHandle::GenerateLayer( FontEffect* font_effect)
+{
+	// See if this effect has been instanced before, as part of a different configuration.
+	FontLayerMap::iterator i = layers.find(font_effect);
+	if (i != layers.end())
+		return i->second;
+
+	Rocket::Core::FontFaceLayer* layer = new Rocket::Core::BitmapFont::FontFaceLayer();
+	layers[font_effect] = layer;
+
+	if (font_effect == NULL)
+	{
+		layer->Initialise(this);
+	}
+	else
+	{
+		// Determine which, if any, layer the new layer should copy its geometry and textures from.
+		Rocket::Core::FontFaceLayer* clone = NULL;
+		bool deep_clone = true;
+		String generation_key;
+
+		if (!font_effect->HasUniqueTexture())
+		{
+			clone = base_layer;
+			deep_clone = false;
+		}
+		else
+		{
+			generation_key = font_effect->GetName() + ";" + font_effect->GetGenerationKey();
+			FontLayerCache::iterator cache_iterator = layer_cache.find(generation_key);
+			if (cache_iterator != layer_cache.end())
+				clone = cache_iterator->second;
+		}
+
+		// Create a new layer.
+		layer->Initialise(this, font_effect, clone, deep_clone);
+
+		// Cache the layer in the layer cache if it generated its own textures (ie, didn't clone).
+		if (clone == NULL)
+			layer_cache[generation_key] = (Rocket::Core::FontFaceLayer*) layer;
+	}
+
+	return (Rocket::Core::FontFaceLayer*)layer;
+}
+
+}
+}
+}

+ 136 - 0
Source/Core/BitmapFont/FontFaceHandle.h

@@ -0,0 +1,136 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * 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 ROCKETCOREBITMAPFONTFONTFACEHANDLE_H
+#define ROCKETCOREBITMAPFONTFONTFACEHANDLE_H
+
+#include "../UnicodeRange.h"
+#include "../../../Include/Rocket/Core/Font.h"
+#include "../../../Include/Rocket/Core/FontEffect.h"
+#include "../../../Include/Rocket/Core/FontGlyph.h"
+#include "../../../Include/Rocket/Core/Geometry.h"
+#include "../../../Include/Rocket/Core/String.h"
+#include "../../../Include/Rocket/Core/Texture.h"
+#include "../FontFaceHandle.h"
+#include "BitmapFontDefinitions.h"
+
+namespace Rocket {
+namespace Core {
+namespace BitmapFont {
+
+/**
+	@author Peter Curry
+ */
+
+class FontFaceHandle : public Rocket::Core::FontFaceHandle
+{
+public:
+	FontFaceHandle();
+	virtual ~FontFaceHandle();
+
+	/// Initialises the handle so it is able to render text.
+	/// @param[in] ft_face The FreeType face that this handle is rendering.
+	/// @param[in] charset The comma-separated list of unicode ranges this handle must support.
+	/// @param[in] size The size, in points, of the face this handle should render at.
+	/// @return True if the handle initialised successfully and is ready for rendering, false if an error occured.
+	bool Initialise(BitmapFontDefinitions *bm_face, const String& charset, int size);
+
+	/// Returns the width a string will take up if rendered with this handle.
+	/// @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.
+	int GetStringWidth(const WString& string, word prior_character = 0) const;
+
+	/// Generates, if required, the layer configuration for a given array of font effects.
+	/// @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.
+	int GenerateLayerConfiguration(Rocket::Core::FontEffectMap& font_effects);
+
+	/// 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.
+	/// @param[out] texture_dimensions The dimensions of the texture.
+	/// @param[in] layer_id The id of the layer to request the texture data from.
+	/// @param[in] texture_id The index of the texture within the layer to generate.
+	bool GenerateLayerTexture(const byte*& texture_data, Vector2i& texture_dimensions, FontEffect* layer_id, int texture_id);
+
+	/// 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] 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.
+	int GenerateString(GeometryList& geometry, const WString& string, const Vector2f& position, const Colourb& colour, int layer_configuration = 0) const;
+
+	/// 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] height The height to render the line at.
+	/// @param[in] colour The colour to draw the line in.
+	void GenerateLine(Geometry* geometry, const Vector2f& position, int width, Font::Line height, const Colourb& colour) const;
+
+	const String & GetTextureSource() const
+	{
+		return texture_source;
+	}
+
+	unsigned int GetTextureWidth() const
+	{
+		return texture_width;
+	}
+
+	unsigned int GetTextureHeight() const
+	{
+		return texture_height;
+	}
+
+protected:
+	/// Destroys the handle.
+	virtual void OnReferenceDeactivate();
+
+private:
+	void GenerateMetrics(BitmapFontDefinitions *bm_face);
+
+	void BuildGlyphMap(BitmapFontDefinitions *bm_face, const UnicodeRange& unicode_range);
+	void BuildGlyph(FontGlyph& glyph, CharacterInfo *ft_glyph);
+	int GetKerning(word lhs, word rhs) const;
+
+	// Generates (or shares) a layer derived from a font effect.
+	virtual FontFaceLayer* GenerateLayer(FontEffect* font_effect);
+
+	BitmapFontDefinitions * bm_face;
+	String texture_source;
+	String texture_directory;
+	unsigned int texture_width;
+	unsigned int texture_height;
+};
+
+}
+}
+}
+
+#endif

+ 127 - 0
Source/Core/BitmapFont/FontFaceLayer.cpp

@@ -0,0 +1,127 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * 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.
+ *
+ */
+
+#include "../precompiled.h"
+#include "FontFaceLayer.h"
+#include "FontFaceHandle.h"
+
+namespace Rocket {
+namespace Core {
+namespace BitmapFont {
+
+FontFaceLayer::FontFaceLayer() : Rocket::Core::FontFaceLayer()
+{
+	handle = NULL;
+	effect = NULL;
+}
+
+FontFaceLayer::~FontFaceLayer()
+{
+}
+
+// Generates the character and texture data for the layer.
+bool FontFaceLayer::Initialise(const Rocket::Core::FontFaceHandle* _handle, FontEffect* _effect, const Rocket::Core::FontFaceLayer* clone, bool deep_clone)
+{
+	(void)(_effect);
+
+	Rocket::Core::BitmapFont::FontFaceHandle
+		* bm_font_face_handle;
+
+	handle = _handle;
+
+	bm_font_face_handle = ( Rocket::Core::BitmapFont::FontFaceHandle * ) handle;
+
+	const FontGlyphList& glyphs = handle->GetGlyphs();
+
+	// Clone the geometry and textures from the clone layer.
+	if (clone != NULL)
+	{
+		// Copy the cloned layer's characters.
+		characters = clone->characters;
+
+		// Copy (and reference) the cloned layer's textures.
+		for (size_t i = 0; i < clone->textures.size(); ++i)
+			textures.push_back(clone->textures[i]);
+	}
+	else
+	{
+		// Load texture from file
+		Texture texture;
+		if (!texture.Load( bm_font_face_handle->GetTextureSource() ))
+			return false;
+
+		textures.push_back(texture);
+
+		// Initialise the texture layout for the glyphs.
+		characters.resize(glyphs.size(), Character());
+		for (FontGlyphList::const_iterator i = glyphs.begin(); i != glyphs.end(); ++i)
+		{
+			const FontGlyph& glyph = *i;
+
+			if(glyph.dimensions.x <= 0 || glyph.dimensions.y <= 0)
+				continue;
+
+			Vector2i glyph_origin( glyph.bitmap_dimensions.x, glyph.bitmap_dimensions.y ); // position in texture
+			Vector2i glyph_dimensions = glyph.dimensions; // size of char
+
+			Character character;
+			character.origin = Vector2f((float) (glyph.bearing.x), (float) (glyph.bearing.y) - handle->GetBaseline()*3 );
+			character.dimensions = Vector2f((float) glyph.dimensions.x, (float) glyph.dimensions.y);
+
+			// Set the character's texture index.
+			character.texture_index = 0;
+
+			// Generate the character's texture coordinates.
+			character.texcoords[0].x = float(glyph_origin.x) / float(bm_font_face_handle->GetTextureWidth());
+			character.texcoords[0].y = float(glyph_origin.y) / float(bm_font_face_handle->GetTextureHeight());
+			character.texcoords[1].x = float(glyph_origin.x + character.dimensions.x) / float(bm_font_face_handle->GetTextureWidth());
+			character.texcoords[1].y = float(glyph_origin.y + character.dimensions.y) / float(bm_font_face_handle->GetTextureHeight());
+
+			characters[glyph.character] = character;
+
+			// Add the character's dimensions into the texture layout engine.
+			texture_layout.AddRectangle(glyph.character, glyph_dimensions);
+		}
+
+		// Generate the texture layout; this will position the glyph rectangles efficiently and
+		// allocate the texture data ready for writing.
+		if (!texture_layout.GenerateLayout(512))
+			return false;
+
+	}
+	return true;
+}
+
+// Generates the texture data for a layer (for the texture database).
+bool FontFaceLayer::GenerateTexture(const byte*& texture_data, Vector2i& texture_dimensions, int texture_id)
+{
+	return true;
+}
+
+}
+}
+}

+ 78 - 0
Source/Core/BitmapFont/FontFaceLayer.h

@@ -0,0 +1,78 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * 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 ROCKETCOREBITMAPFONTFACELAYER_H
+#define ROCKETCOREBITMAPFONTFACELAYER_H
+
+#include <Rocket/Core/Header.h>
+#include <Rocket/Core/FontGlyph.h>
+#include <Rocket/Core/Geometry.h>
+#include <Rocket/Core/GeometryUtilities.h>
+#include <Rocket/Core/String.h>
+#include "../FontFaceLayer.h"
+
+namespace Rocket {
+namespace Core {
+
+	class TextureLayout;
+
+namespace BitmapFont {
+
+/**
+	A textured layer stored as part of a font face handle. Each handle will have at least a base
+	layer for the standard font. Further layers can be added to allow to rendering of text effects.
+	@author Peter Curry
+ */
+
+class FontFaceLayer : public Rocket::Core::FontFaceLayer
+{
+public:
+	FontFaceLayer();
+	virtual ~FontFaceLayer();
+
+	/// Generates the character and texture data for the layer.
+	/// @param[in] handle The handle generating this layer.
+	/// @param[in] effect The effect to initialise the layer with.
+	/// @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.
+	virtual bool Initialise(const FontFaceHandle* handle, FontEffect* effect = NULL, const Rocket::Core::FontFaceLayer* clone = NULL, 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.
+	/// @param[out] texture_dimensions The dimensions of the texture.
+	/// @param[in] glyphs The glyphs required by the font face handle.
+	/// @param[in] texture_id The index of the texture within the layer to generate.
+	virtual bool GenerateTexture(const byte*& texture_data, Vector2i& texture_dimensions, int texture_id);
+
+};
+
+}
+}
+}
+
+#endif

+ 55 - 0
Source/Core/BitmapFont/FontFamily.cpp

@@ -0,0 +1,55 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * 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.
+ *
+ */
+
+#include "../precompiled.h"
+#include "FontFamily.h"
+#include "FontFace.h"
+
+namespace Rocket {
+namespace Core {
+namespace BitmapFont {
+
+FontFamily::FontFamily(const String& name) : Rocket::Core::FontFamily(name)
+{
+}
+
+FontFamily::~FontFamily()
+{
+}
+
+// Adds a new face to the family.
+bool FontFamily::AddFace( void *bm_face, Font::Style style, Font::Weight weight, bool release_stream)
+{
+	Rocket::Core::FontFace* face = new FontFace((BitmapFontDefinitions*)bm_face, style, weight, release_stream);
+	font_faces.push_back(face);
+
+	return true;
+}
+
+}
+}
+}

+ 66 - 0
Source/Core/BitmapFont/FontFamily.h

@@ -0,0 +1,66 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * 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 ROCKETCOREBITMAPFONTFAMILY_H
+#define ROCKETCOREBITMAPFONTFAMILY_H
+
+#include "../../../Include/Rocket/Core/Font.h"
+#include "../../../Include/Rocket/Core/FontFamily.h"
+#include "BitmapFontDefinitions.h"
+
+namespace Rocket {
+namespace Core {
+
+class FontFace;
+class FontFaceHandle;
+
+namespace BitmapFont {
+
+/**
+	@author Peter Curry
+ */
+
+class FontFamily : public Rocket::Core::FontFamily
+{
+public:
+	FontFamily(const String& name);
+	~FontFamily();
+
+	/// Adds a new face to the family.
+	/// @param[in] ft_face The previously loaded FreeType face.
+	/// @param[in] style The style of the new face.
+	/// @param[in] weight The weight of the new face.
+	/// @param[in] release_stream True if the application must free the face's memory stream.
+	/// @return True if the face was loaded successfully, false otherwise.
+	bool AddFace( void *bm_face, Font::Style style, Font::Weight weight, bool release_stream);
+};
+
+}
+}
+}
+
+#endif

+ 112 - 0
Source/Core/BitmapFont/FontParser.cpp

@@ -0,0 +1,112 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * 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.
+ *
+ */
+
+#include "../precompiled.h"
+#include "FontParser.h"
+
+namespace Rocket {
+namespace Core {
+namespace BitmapFont {
+
+FontParser::FontParser( BitmapFontDefinitions *face )
+	: BaseXMLParser()
+{
+	bm_face = face;
+	char_id = 0;
+	kern_id = 0;
+}
+
+FontParser::~FontParser()
+{
+}
+
+// Called when the parser finds the beginning of an element tag.
+void FontParser::HandleElementStart(const String& name, const XMLAttributes& attributes)
+{
+	if ( name == "info" )
+	{
+		bm_face->Face.FamilyName = attributes.Get( "face" )->Get< String >();
+		bm_face->Face.Size = attributes.Get( "size" )->Get< int >();
+		bm_face->Face.Weight = attributes.Get( "bold" )->Get< bool >() ? Font::WEIGHT_BOLD : Font::WEIGHT_NORMAL;
+		bm_face->Face.Style = attributes.Get( "italic" )->Get< bool >() ? Font::STYLE_ITALIC : Font::STYLE_NORMAL;
+		bm_face->Face.BitmapSource = attributes.Get( "src" )->Get< String >();
+	}
+	else if ( name == "common" )
+	{
+		bm_face->CommonCharactersInfo.LineHeight = attributes.Get( "lineHeight" )->Get< int >();
+		bm_face->CommonCharactersInfo.BaseLine = attributes.Get( "base" )->Get< int >() * -1;
+		bm_face->CommonCharactersInfo.ScaleWidth = attributes.Get( "scaleW" )->Get< int >();
+		bm_face->CommonCharactersInfo.ScaleHeight = attributes.Get( "scaleH" )->Get< int >();
+		bm_face->CommonCharactersInfo.CharacterCount = 0;
+		bm_face->CommonCharactersInfo.KerningCount = 0;
+	}
+	else if ( name == "chars" )
+	{
+		bm_face->CommonCharactersInfo.CharacterCount = attributes.Get( "count" )->Get< int >();
+		bm_face->CharactersInfo = new CharacterInfo[ attributes.Get( "count" )->Get< int >() ];
+	}
+	else if ( name == "char" )
+	{
+		bm_face->CharactersInfo[ char_id ].Id = attributes.Get( "id" )->Get< int >();
+		bm_face->CharactersInfo[ char_id ].X = attributes.Get( "x" )->Get< int >(); //The left position of the character image in the texture.
+		bm_face->CharactersInfo[ char_id ].Y = attributes.Get( "y" )->Get< int >(); //The top position of the character image in the texture.
+		bm_face->CharactersInfo[ char_id ].Width = attributes.Get( "width" )->Get< int >(); //The width of the character image in the texture.
+		bm_face->CharactersInfo[ char_id ].Height = attributes.Get( "height" )->Get< int >(); //The height of the character image in the texture.
+		bm_face->CharactersInfo[ char_id ].XOffset = attributes.Get( "xoffset" )->Get< int >();
+		bm_face->CharactersInfo[ char_id ].YOffset = attributes.Get( "yoffset" )->Get< int >();
+		bm_face->CharactersInfo[ char_id ].Advance = attributes.Get( "xadvance" )->Get< int >();
+
+		char_id++;
+	}
+	else if ( name == "kernings" )
+	{
+		bm_face->CommonCharactersInfo.KerningCount = attributes.Get( "count" )->Get< int >();
+		bm_face->KerningsInfo = new KerningInfo[ attributes.Get( "count" )->Get< int >() ];
+	}
+	else if ( name == "kerning" )
+	{
+		bm_face->KerningsInfo[ kern_id ].FirstCharacterId = attributes.Get( "first" )->Get< int >();
+		bm_face->KerningsInfo[ kern_id ].SecondCharacterId = attributes.Get( "second" )->Get< int >();
+		bm_face->KerningsInfo[ kern_id ].KerningAmount = attributes.Get( "amount" )->Get< int >();
+
+		kern_id++;
+	}
+}
+
+// Called when the parser finds the end of an element tag.
+void FontParser::HandleElementEnd(const String& ROCKET_UNUSED(name))
+{
+}
+
+// Called when the parser encounters data.
+void FontParser::HandleData(const String& ROCKET_UNUSED(data))
+{
+}
+
+}
+}
+}

+ 68 - 0
Source/Core/BitmapFont/FontParser.h

@@ -0,0 +1,68 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * 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 BITMAPFONTPARSER_H
+#define BITMAPFONTPARSER_H
+
+#include <Rocket/Core/Header.h>
+#include <Rocket/Core/Types.h>
+#include <Rocket/Core/Dictionary.h>
+#include "BitmapFontDefinitions.h"
+#include <set>
+
+namespace Rocket {
+namespace Core {
+namespace BitmapFont {
+
+/**
+	@author Peter Curry
+ */
+
+class FontParser : public BaseXMLParser
+{
+	public:
+		FontParser( BitmapFontDefinitions *face );
+		virtual ~FontParser();
+
+		/// Called when the parser finds the beginning of an element tag.
+		virtual void HandleElementStart(const String& name, const XMLAttributes& attributes);
+		/// Called when the parser finds the end of an element tag.
+		virtual void HandleElementEnd(const String& name);
+		/// Called when the parser encounters data.
+		virtual void HandleData(const String& data);
+
+	private:
+		FontParser();
+		BitmapFontDefinitions *bm_face;
+		int char_id;
+		int kern_id;
+};
+
+}
+}
+}
+#endif

+ 208 - 0
Source/Core/BitmapFont/FontProvider.cpp

@@ -0,0 +1,208 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * 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.
+ *
+ */
+
+#include "../precompiled.h"
+#include <Rocket/Core/BitmapFont/FontProvider.h>
+#include "../FontFaceHandle.h"
+#include <Rocket/Core/FontDatabase.h>
+#include <Rocket/Core/StreamMemory.h>
+#include "FontFamily.h"
+#include <Rocket/Core.h>
+#include "BitmapFontDefinitions.h"
+#include "FontParser.h"
+
+namespace Rocket {
+namespace Core {
+namespace BitmapFont {
+
+
+FontProvider* FontProvider::instance = NULL;
+
+FontProvider::FontProvider()
+{
+	ROCKET_ASSERT(instance == NULL);
+	instance = this;
+}
+
+FontProvider::~FontProvider()
+{
+	ROCKET_ASSERT(instance == this);
+	instance = NULL;
+}
+
+bool FontProvider::Initialise()
+{
+	if (instance == NULL)
+	{
+		new FontProvider();
+
+		FontDatabase::AddFontProvider(instance);
+	}
+
+	return true;
+}
+
+void FontProvider::Shutdown()
+{
+	if (instance != NULL)
+	{
+		FontDatabase::RemoveFontProvider(instance);
+		delete instance;
+		instance = NULL;
+	}
+}
+
+// Adds a new font face to the database, ignoring any family, style and weight information stored in the face itself.
+bool FontProvider::LoadFontFace(const String& file_name)
+{
+	BitmapFontDefinitions *bm_font = (BitmapFontDefinitions*) instance->LoadFace(file_name);
+
+	if (bm_font == NULL)
+	{
+		Log::Message(Log::LT_ERROR, "Failed to load font face from %s.", file_name.CString());
+		return false;
+	}
+
+	Font::Style style = bm_font->Face.Style;
+	Font::Weight weight = bm_font->Face.Weight;
+
+	if (instance->AddFace(bm_font, bm_font->Face.FamilyName, style, weight, true))
+	{
+		Log::Message(Log::LT_INFO, "Loaded font face %s (from %s).", bm_font->Face.FamilyName.CString(), file_name.CString());
+		return true;
+	}
+	else
+	{
+		Log::Message(Log::LT_ERROR, "Failed to load font face %s (from %s).", bm_font->Face.FamilyName.CString(), file_name.CString());
+		return false;
+	}
+
+	return true;
+}
+
+// Loads a new font face.
+bool FontProvider::LoadFontFace(const String& file_name, const String& family, Font::Style style, Font::Weight weight)
+{
+	BitmapFontDefinitions *bm_font = (BitmapFontDefinitions*) instance->LoadFace(file_name);
+	if (bm_font == NULL)
+	{
+		Log::Message(Log::LT_ERROR, "Failed to load font face from %s.", file_name.CString());
+		return false;
+	}
+
+	if (instance->AddFace(bm_font, family, style, weight, true))
+	{
+		Log::Message(Log::LT_INFO, "Loaded font face %s (from %s).", bm_font->Face.FamilyName.CString(), file_name.CString());
+		return true;
+	}
+	else
+	{
+		Log::Message(Log::LT_ERROR, "Failed to load font face %s (from %s).", bm_font->Face.FamilyName.CString(), file_name.CString());
+		return false;
+	}
+
+	return true;
+}
+
+bool FontProvider::LoadFontFace(const byte* data, int data_length)
+{
+	// TODO: Loading from memory
+	return false;
+}
+
+// Adds a new font face to the database, loading from memory.
+bool FontProvider::LoadFontFace(const byte* data, int data_length, const String& family, Font::Style style, Font::Weight weight)
+{
+	// TODO Loading from memory
+	return false;
+}
+
+// Adds a loaded face to the appropriate font family.
+bool FontProvider::AddFace(void* face, const String& family, Font::Style style, Font::Weight weight, bool release_stream)
+{
+	Rocket::Core::FontFamily* font_family = NULL;
+	FontFamilyMap::iterator iterator = instance->font_families.find(family);
+	if (iterator != instance->font_families.end())
+		font_family = (*iterator).second;
+	else
+	{
+		font_family = new FontFamily(family);
+		instance->font_families[family] = font_family;
+	}
+
+	return font_family->AddFace((BitmapFontDefinitions *) face, style, weight, release_stream);
+	return true;
+}
+
+// Loads a FreeType face.
+void* FontProvider::LoadFace(const String& file_name)
+{
+	BitmapFontDefinitions *bm_face = new BitmapFontDefinitions();
+	FontParser parser( bm_face );
+
+	FileInterface* file_interface = GetFileInterface();
+	FileHandle handle = file_interface->Open(file_name);
+
+	if (!handle)
+	{
+		return NULL;
+	}
+
+	size_t length = file_interface->Length(handle);
+
+	byte* buffer = new byte[length];
+	file_interface->Read(buffer, length, handle);
+	file_interface->Close(handle);
+
+	StreamMemory* stream = new StreamMemory( buffer, length );
+	stream->SetSourceURL( file_name );
+
+	parser.Parse( stream );
+
+	bm_face->Face.Source = file_name;
+	return bm_face;
+}
+
+// Loads a FreeType face from memory.
+void* FontProvider::LoadFace(const byte* data, int data_length, const String& source, bool local_data)
+{
+	URL file_url = source + ".fnt";
+
+	BitmapFontDefinitions *bm_face = new BitmapFontDefinitions();
+	FontParser parser( bm_face );
+	StreamMemory* stream = new StreamMemory( data, data_length );
+	stream->SetSourceURL( file_url );
+
+	parser.Parse( stream );
+
+	bm_face->Face.Source = file_url.GetPathedFileName();
+	return bm_face;
+}
+
+}
+}
+}

+ 6 - 1
Source/Core/DecoratorTiled.cpp

@@ -108,6 +108,11 @@ Vector2f DecoratorTiled::Tile::GetDimensions(Element* element)
 void DecoratorTiled::Tile::GenerateGeometry(std::vector< Vertex >& vertices, std::vector< int >& indices, Element* element, const Vector2f& surface_origin, const Vector2f& surface_dimensions, const Vector2f& tile_dimensions) const
 void DecoratorTiled::Tile::GenerateGeometry(std::vector< Vertex >& vertices, std::vector< int >& indices, Element* element, const Vector2f& surface_origin, const Vector2f& surface_dimensions, const Vector2f& tile_dimensions) const
 {
 {
 	RenderInterface* render_interface = element->GetRenderInterface();
 	RenderInterface* render_interface = element->GetRenderInterface();
+	const Property* element_colour = element->GetProperty(COLOR);
+	Colourb quad_colour = Colourb(255, 255, 255);
+	if (element_colour)
+		quad_colour = element_colour->Get<Colourb>();
+	
 	TileDataMap::iterator data_iterator = data.find(render_interface);
 	TileDataMap::iterator data_iterator = data.find(render_interface);
 	if (data_iterator == data.end())
 	if (data_iterator == data.end())
 		return;
 		return;
@@ -244,7 +249,7 @@ void DecoratorTiled::Tile::GenerateGeometry(std::vector< Vertex >& vertices, std
 			tile_position.x = surface_origin.x + (float) tile_dimensions.x * x;
 			tile_position.x = surface_origin.x + (float) tile_dimensions.x * x;
 			tile_size.x = (float) (x < num_tiles[0] - 1 ? tile_dimensions.x : final_tile_dimensions.x);
 			tile_size.x = (float) (x < num_tiles[0] - 1 ? tile_dimensions.x : final_tile_dimensions.x);
 
 
-			GeometryUtilities::GenerateQuad(new_vertices, new_indices, tile_position, tile_size, Colourb(255, 255, 255), tile_texcoords[0], tile_texcoords[1], index_offset);
+			GeometryUtilities::GenerateQuad(new_vertices, new_indices, tile_position, tile_size, quad_colour, tile_texcoords[0], tile_texcoords[1], index_offset);
 			new_vertices += 4;
 			new_vertices += 4;
 			new_indices += 6;
 			new_indices += 6;
 			index_offset += 4;
 			index_offset += 4;

+ 7 - 2
Source/Core/Element.cpp

@@ -537,6 +537,11 @@ float Element::ResolveProperty(const Property *property, float base_value)
 	return style->ResolveProperty(property, base_value);
 	return style->ResolveProperty(property, base_value);
 }
 }
 
 
+void Element::GetOffsetProperties(const Property **top, const Property **bottom, const Property **left, const Property **right )
+{
+	style->GetOffsetProperties(top, bottom, left, right);
+}
+
 void Element::GetBorderWidthProperties(const Property **border_top, const Property **border_bottom, const Property **border_left, const Property **bottom_right)
 void Element::GetBorderWidthProperties(const Property **border_top, const Property **border_bottom, const Property **border_left, const Property **bottom_right)
 {
 {
 	style->GetBorderWidthProperties(border_top, border_bottom, border_left, bottom_right);
 	style->GetBorderWidthProperties(border_top, border_bottom, border_left, bottom_right);
@@ -1708,7 +1713,7 @@ void Element::ProcessEvent(Event& event)
 			if (overflow_property == OVERFLOW_AUTO ||
 			if (overflow_property == OVERFLOW_AUTO ||
 				overflow_property == OVERFLOW_SCROLL)
 				overflow_property == OVERFLOW_SCROLL)
 			{
 			{
-				SetScrollTop(GetScrollTop() + wheel_delta * ElementUtilities::GetLineHeight(this));
+				SetScrollTop(GetScrollTop() + wheel_delta * (GetFontFaceHandle() ? ElementUtilities::GetLineHeight(this) : (GetProperty(SCROLL_DEFAULT_STEP_SIZE) ? GetProperty< int >(SCROLL_DEFAULT_STEP_SIZE) : 0 )));
 				event.StopPropagation();
 				event.StopPropagation();
 			}
 			}
 		}
 		}
@@ -1836,7 +1841,7 @@ void Element::UpdateOffset()
 			// If the element is anchored right, then the position is set first so the element's right-most edge
 			// If the element is anchored right, then the position is set first so the element's right-most edge
 			// (including margins) will render up against the containing box's right-most content edge, and then
 			// (including margins) will render up against the containing box's right-most content edge, and then
 			// offset by the resolved value.
 			// offset by the resolved value.
-			if (right != NULL && right->unit != Property::KEYWORD)
+			else if (right != NULL && right->unit != Property::KEYWORD)
 				relative_offset_base.x = containing_block.x + parent_box.GetEdge(Box::BORDER, Box::LEFT) - (ResolveProperty(RIGHT, containing_block.x) + GetBox().GetSize(Box::BORDER).x + GetBox().GetEdge(Box::MARGIN, Box::RIGHT));
 				relative_offset_base.x = containing_block.x + parent_box.GetEdge(Box::BORDER, Box::LEFT) - (ResolveProperty(RIGHT, containing_block.x) + GetBox().GetSize(Box::BORDER).x + GetBox().GetEdge(Box::MARGIN, Box::RIGHT));
 
 
 			const Property *top = GetLocalProperty(TOP);
 			const Property *top = GetLocalProperty(TOP);

+ 1 - 0
Source/Core/ElementDocument.cpp

@@ -492,6 +492,7 @@ bool ElementDocument::SearchFocusSubtree(Element* element, bool forward)
 	if (element->GetProperty<int>(TAB_INDEX) == TAB_INDEX_AUTO)
 	if (element->GetProperty<int>(TAB_INDEX) == TAB_INDEX_AUTO)
 	{
 	{
 		element->Focus();
 		element->Focus();
+		element->ScrollIntoView(false);
 		return true;
 		return true;
 	}
 	}
 
 

+ 5 - 0
Source/Core/ElementStyle.cpp

@@ -729,6 +729,11 @@ void ElementStyle::DirtyInheritedProperties(const PropertyNameList& properties)
 	element->OnPropertyChange(properties);
 	element->OnPropertyChange(properties);
 }
 }
 
 
+void ElementStyle::GetOffsetProperties(const Property **top, const Property **bottom, const Property **left, const Property **right )
+{
+	cache->GetOffsetProperties(top, bottom, left, right);
+}
+
 void ElementStyle::GetBorderWidthProperties(const Property **border_top_width, const Property **border_bottom_width, const Property **border_left_width, const Property **bottom_right_width)
 void ElementStyle::GetBorderWidthProperties(const Property **border_top_width, const Property **border_bottom_width, const Property **border_left_width, const Property **bottom_right_width)
 {
 {
 	cache->GetBorderWidthProperties(border_top_width, border_bottom_width, border_left_width, bottom_right_width);
 	cache->GetBorderWidthProperties(border_top_width, border_bottom_width, border_left_width, bottom_right_width);

+ 2 - 0
Source/Core/ElementStyle.h

@@ -143,6 +143,8 @@ public:
 	// Dirties rem properties.
 	// Dirties rem properties.
 	void DirtyRemProperties();
 	void DirtyRemProperties();
 
 
+	/// Returns 'top', 'bottom', 'left' and 'right' properties from element's style or local cache.
+	void GetOffsetProperties(const Property **top, const Property **bottom, const Property **left, const Property **right );	
 	/// Returns 'border-width' properties from element's style or local cache.
 	/// Returns 'border-width' properties from element's style or local cache.
 	void GetBorderWidthProperties(const Property **border_top_width, const Property **border_bottom_width, const Property **border_left_width, const Property **border_right_width);
 	void GetBorderWidthProperties(const Property **border_top_width, const Property **border_bottom_width, const Property **border_left_width, const Property **border_right_width);
 	/// Returns 'margin' properties from element's style or local cache.
 	/// Returns 'margin' properties from element's style or local cache.

+ 38 - 0
Source/Core/ElementStyleCache.cpp

@@ -33,6 +33,7 @@ namespace Rocket {
 namespace Core {
 namespace Core {
 
 
 ElementStyleCache::ElementStyleCache(ElementStyle *style) : style(style), 
 ElementStyleCache::ElementStyleCache(ElementStyle *style) : style(style), 
+	top(NULL), bottom(NULL), left(NULL), right(NULL),
 	border_top_width(NULL), border_bottom_width(NULL), border_left_width(NULL), border_right_width(NULL),
 	border_top_width(NULL), border_bottom_width(NULL), border_left_width(NULL), border_right_width(NULL),
 	margin_top(NULL), margin_bottom(NULL), margin_left(NULL), margin_right(NULL),
 	margin_top(NULL), margin_bottom(NULL), margin_left(NULL), margin_right(NULL),
 	padding_top(NULL), padding_bottom(NULL), padding_left(NULL), padding_right(NULL),
 	padding_top(NULL), padding_bottom(NULL), padding_left(NULL), padding_right(NULL),
@@ -46,6 +47,7 @@ ElementStyleCache::ElementStyleCache(ElementStyle *style) : style(style),
 
 
 void ElementStyleCache::Clear()
 void ElementStyleCache::Clear()
 {
 {
+	ClearOffset();
 	ClearBorder();
 	ClearBorder();
 	ClearMargin();
 	ClearMargin();
 	ClearPadding();
 	ClearPadding();
@@ -65,6 +67,11 @@ void ElementStyleCache::ClearInherited()
 	ClearVerticalAlign();
 	ClearVerticalAlign();
 }
 }
 
 
+void ElementStyleCache::ClearOffset()
+{
+	top = bottom = left = right = NULL;
+}
+
 void ElementStyleCache::ClearBorder()
 void ElementStyleCache::ClearBorder()
 {
 {
 	border_top_width = border_bottom_width = border_left_width = border_right_width = NULL;
 	border_top_width = border_bottom_width = border_left_width = border_right_width = NULL;
@@ -131,6 +138,37 @@ void ElementStyleCache::ClearVerticalAlign()
 	vertical_align = NULL;
 	vertical_align = NULL;
 }
 }
 
 
+void ElementStyleCache::GetOffsetProperties(const Property **o_top, const Property **o_bottom, const Property **o_left, const Property **o_right )
+{
+	if (o_top)
+	{
+		if (!top)
+			top = style->GetProperty(TOP);
+		*o_top = top;
+	}
+
+	if (o_bottom)
+	{
+		if (!bottom)
+			bottom = style->GetProperty(BOTTOM);
+		*o_bottom = bottom;
+	}
+
+	if (o_left)
+	{
+		if (!left)
+			left = style->GetProperty(LEFT);
+		*o_left = left;
+	}
+
+	if (o_right)
+	{
+		if (!right)
+			right = style->GetProperty(RIGHT);
+		*o_right = right;
+	}
+}
+
 void ElementStyleCache::GetBorderWidthProperties(const Property **o_border_top_width, const Property **o_border_bottom_width, const Property **o_border_left_width, const Property **o_border_right_width)
 void ElementStyleCache::GetBorderWidthProperties(const Property **o_border_top_width, const Property **o_border_bottom_width, const Property **o_border_left_width, const Property **o_border_right_width)
 {
 {
 	if (o_border_top_width)
 	if (o_border_top_width)

+ 4 - 0
Source/Core/ElementStyleCache.h

@@ -55,6 +55,7 @@ public:
 	void ClearInherited();
 	void ClearInherited();
 
 
 	/// Invalidation functions for individual and grouped non-inherited properties
 	/// Invalidation functions for individual and grouped non-inherited properties
+	void ClearOffset();
 	void ClearBorder();
 	void ClearBorder();
 	void ClearMargin();
 	void ClearMargin();
 	void ClearPadding();
 	void ClearPadding();
@@ -71,6 +72,8 @@ public:
 	void ClearTextTransform();
 	void ClearTextTransform();
 	void ClearVerticalAlign();
 	void ClearVerticalAlign();
 
 
+	/// Returns 'top', 'bottom', 'left' and 'right' properties from element's style or local cache.
+	void GetOffsetProperties(const Property **top, const Property **bottom, const Property **left, const Property **right );
 	/// Returns 'border-width' properties from element's style or local cache.
 	/// Returns 'border-width' properties from element's style or local cache.
 	void GetBorderWidthProperties(const Property **border_top_width, const Property **border_bottom_width, const Property **border_left_width, const Property **border_right_width);
 	void GetBorderWidthProperties(const Property **border_top_width, const Property **border_bottom_width, const Property **border_left_width, const Property **border_right_width);
 	/// Returns 'margin' properties from element's style or local cache.
 	/// Returns 'margin' properties from element's style or local cache.
@@ -107,6 +110,7 @@ private:
 	ElementStyle *style;
 	ElementStyle *style;
 
 
 	/// Cached properties.
 	/// Cached properties.
+	const Property *top, *bottom, *left, *right;
 	const Property *border_top_width, *border_bottom_width, *border_left_width, *border_right_width;
 	const Property *border_top_width, *border_bottom_width, *border_left_width, *border_right_width;
 	const Property *margin_top, *margin_bottom, *margin_left, *margin_right;
 	const Property *margin_top, *margin_bottom, *margin_left, *margin_right;
 	const Property *padding_top, *padding_bottom, *padding_left, *padding_right;
 	const Property *padding_top, *padding_bottom, *padding_left, *padding_right;

+ 94 - 158
Source/Core/FontDatabase.cpp

@@ -26,22 +26,21 @@
  */
  */
 
 
 #include "precompiled.h"
 #include "precompiled.h"
-#include "../../Include/Rocket/Core/FontDatabase.h"
-#include "FontFamily.h"
-#include "../../Include/Rocket/Core.h"
-#include <ft2build.h>
-#include FT_FREETYPE_H
+#include <Rocket/Core/FontDatabase.h>
+#include <Rocket/Core/FontFamily.h>
+#include <Rocket/Core.h>
+#include <Rocket/Core/FreeType/FontProvider.h>
+#include <Rocket/Core/BitmapFont/FontProvider.h>
 
 
 namespace Rocket {
 namespace Rocket {
 namespace Core {
 namespace Core {
 
 
 FontDatabase* FontDatabase::instance = NULL;
 FontDatabase* FontDatabase::instance = NULL;
+FontDatabase::FontProviderTable FontDatabase::font_provider_table;
 
 
 typedef std::map< String, FontEffect* > FontEffectCache;
 typedef std::map< String, FontEffect* > FontEffectCache;
 FontEffectCache font_effect_cache;
 FontEffectCache font_effect_cache;
 
 
-static FT_Library ft_library = NULL;
-
 FontDatabase::FontDatabase()
 FontDatabase::FontDatabase()
 {
 {
 	ROCKET_ASSERT(instance == NULL);
 	ROCKET_ASSERT(instance == NULL);
@@ -60,13 +59,11 @@ bool FontDatabase::Initialise()
 	{
 	{
 		new FontDatabase();
 		new FontDatabase();
 
 
-		FT_Error result = FT_Init_FreeType(&ft_library);
-		if (result != 0)
-		{
-			Log::Message(Log::LT_ERROR, "Failed to initialise FreeType, error %d.", result);
-			Shutdown();
-			return false;
-		}
+        if(!FreeType::FontProvider::Initialise())
+            return false;
+
+        if(!BitmapFont::FontProvider::Initialise())
+            return false;
 	}
 	}
 
 
 	return true;
 	return true;
@@ -76,14 +73,8 @@ void FontDatabase::Shutdown()
 {
 {
 	if (instance != NULL)
 	if (instance != NULL)
 	{
 	{
-		for (FontFamilyMap::iterator i = instance->font_families.begin(); i != instance->font_families.end(); ++i)
-			delete (*i).second;
-
-		if (ft_library != NULL)
-		{
-			FT_Done_FreeType(ft_library);
-			ft_library = NULL;
-		}
+        FreeType::FontProvider::Shutdown();
+        BitmapFont::FontProvider::Shutdown();
 
 
 		delete instance;
 		delete instance;
 	}
 	}
@@ -92,105 +83,101 @@ void FontDatabase::Shutdown()
 // Loads a new font face.
 // Loads a new font face.
 bool FontDatabase::LoadFontFace(const String& file_name)
 bool FontDatabase::LoadFontFace(const String& file_name)
 {
 {
-	FT_Face ft_face = (FT_Face) instance->LoadFace(file_name);
-	if (ft_face == NULL)
-	{
-		Log::Message(Log::LT_ERROR, "Failed to load font face from %s.", file_name.CString());
-		return false;
-	}
+    FontProviderType font_provider_type = GetFontProviderType(file_name);
 
 
-	Font::Style style = ft_face->style_flags & FT_STYLE_FLAG_ITALIC ? Font::STYLE_ITALIC : Font::STYLE_NORMAL;
-	Font::Weight weight = ft_face->style_flags & FT_STYLE_FLAG_BOLD ? Font::WEIGHT_BOLD : Font::WEIGHT_NORMAL;
+    switch(font_provider_type)
+    {
+        case FreeType:
+            return FreeType::FontProvider::LoadFontFace(file_name);
 
 
-	if (instance->AddFace(ft_face, ft_face->family_name, 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.CString());
-		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.CString());
-		return false;
-	}
+        case BitmapFont:
+            return BitmapFont::FontProvider::LoadFontFace(file_name);
+
+        default:
+            return false;
+    }
 }
 }
 
 
 // Adds a new font face to the database, ignoring any family, style and weight information stored in the face itself.
 // 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, Font::Style style, Font::Weight weight)
 bool FontDatabase::LoadFontFace(const String& file_name, const String& family, Font::Style style, Font::Weight weight)
 {
 {
-	FT_Face ft_face = (FT_Face) instance->LoadFace(file_name);
-	if (ft_face == NULL)
-	{
-		Log::Message(Log::LT_ERROR, "Failed to load font face from %s.", file_name.CString());
-		return false;
-	}
+    FontProviderType font_provider_type = GetFontProviderType(file_name);
 
 
-	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.CString());
-		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.CString());
-		return false;
-	}
+    switch(font_provider_type)
+    {
+        case FreeType:
+            return FreeType::FontProvider::LoadFontFace(file_name, family, style, weight);
+
+        case BitmapFont:
+            return BitmapFont::FontProvider::LoadFontFace(file_name, family, style, weight);
+
+        default:
+            return false;
+    }
 }
 }
 
 
 // Adds a new font face to the database, loading from memory.
 // Adds a new font face to the database, loading from memory.
-bool FontDatabase::LoadFontFace(const byte* data, int data_length)
+bool FontDatabase::LoadFontFace(FontProviderType font_provider_type, const byte* data, int data_length)
 {
 {
-	FT_Face ft_face = (FT_Face) instance->LoadFace(data, data_length, "memory", false);
-	if (ft_face == NULL)
-	{
-		Log::Message(Log::LT_ERROR, "Failed to load font face from byte stream.");
-		return false;
-	}
+    switch(font_provider_type)
+    {
+        case FreeType:
+            return FreeType::FontProvider::LoadFontFace(data, data_length);
 
 
-	Font::Style style = ft_face->style_flags & FT_STYLE_FLAG_ITALIC ? Font::STYLE_ITALIC : Font::STYLE_NORMAL;
-	Font::Weight weight = ft_face->style_flags & FT_STYLE_FLAG_BOLD ? Font::WEIGHT_BOLD : Font::WEIGHT_NORMAL;
+        case BitmapFont:
+            return BitmapFont::FontProvider::LoadFontFace(data, data_length);
 
 
-	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;
-	}
+        default:
+            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.
 // 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, Font::Style style, Font::Weight weight)
+bool FontDatabase::LoadFontFace(FontProviderType font_provider_type, const byte* data, int data_length, const String& family, Font::Style style, Font::Weight weight)
 {
 {
-	FT_Face ft_face = (FT_Face) instance->LoadFace(data, data_length, "memory", false);
-	if (ft_face == NULL)
-	{
-		Log::Message(Log::LT_ERROR, "Failed to load font face from byte stream.");
-		return false;
-	}
+    switch(font_provider_type)
+    {
+        case FreeType:
+            return FreeType::FontProvider::LoadFontFace(data, data_length, family, style, weight);
 
 
-	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;
-	}
+        case BitmapFont:
+            return BitmapFont::FontProvider::LoadFontFace(data, data_length, family, style, weight);
+
+        default:
+            return false;
+    }
+}
+
+FontDatabase::FontProviderType FontDatabase::GetFontProviderType(const String& file_name)
+{
+    if(file_name.Find(".fnt") != String::npos)
+    {
+        return BitmapFont;
+    }
+    else
+    {
+        return FreeType;
+    }
 }
 }
 
 
 // Returns a handle to a font face that can be used to position and render text.
 // Returns a handle to a font face that can be used to position and render text.
 FontFaceHandle* FontDatabase::GetFontFaceHandle(const String& family, const String& charset, Font::Style style, Font::Weight weight, int size)
 FontFaceHandle* FontDatabase::GetFontFaceHandle(const String& family, const String& charset, Font::Style style, Font::Weight weight, int size)
 {
 {
-	FontFamilyMap::iterator iterator = instance->font_families.find(family);
-	if (iterator == instance->font_families.end())
-		return NULL;
+    size_t provider_index, provider_count;
+
+    provider_count = font_provider_table.size();
+
+    for(provider_index = 0; provider_index < provider_count; ++provider_index)
+    {
+        FontFaceHandle * face_handle = font_provider_table[ provider_index ]->GetFontFaceHandle(family, charset, style, weight, size);
+
+        if(face_handle)
+        {
+            return face_handle;
+        }
+    }
 
 
-	return (*iterator).second->GetFaceHandle(charset, style, weight, size);
+    return NULL;
 }
 }
 
 
 // Returns a font effect, either a newly-instanced effect from the factory or an identical shared
 // Returns a font effect, either a newly-instanced effect from the factory or an identical shared
@@ -255,72 +242,21 @@ void FontDatabase::ReleaseFontEffect(const FontEffect* effect)
 	}
 	}
 }
 }
 
 
-// Adds a loaded face to the appropriate font family.
-bool FontDatabase::AddFace(void* face, const String& family, Font::Style style, Font::Weight weight, bool release_stream)
+void FontDatabase::AddFontProvider(FontProvider * provider)
 {
 {
-	FontFamily* font_family = NULL;
-	FontFamilyMap::iterator iterator = instance->font_families.find(family);
-	if (iterator != instance->font_families.end())
-		font_family = (*iterator).second;
-	else
-	{
-		font_family = new FontFamily(family);
-		instance->font_families[family] = font_family;
-	}
-
-	return font_family->AddFace((FT_Face) face, style, weight, release_stream);
+    instance->font_provider_table.push_back(provider);
 }
 }
 
 
-// Loads a FreeType face.
-void* FontDatabase::LoadFace(const String& file_name)
+void FontDatabase::RemoveFontProvider(FontProvider * provider)
 {
 {
-	FileInterface* file_interface = GetFileInterface();
-	FileHandle handle = file_interface->Open(file_name);
-
-	if (!handle)
-	{
-		return NULL;
-	}
-
-	size_t length = file_interface->Length(handle);
-
-	FT_Byte* buffer = new FT_Byte[length];
-	file_interface->Read(buffer, length, handle);
-	file_interface->Close(handle);
-
-	return LoadFace(buffer, (int)length, file_name, true);
-}
-
-// Loads a FreeType face from memory.
-void* FontDatabase::LoadFace(const byte* data, int data_length, const String& source, bool local_data)
-{
-	FT_Face face = NULL;
-	int error = FT_New_Memory_Face(ft_library, (const FT_Byte*) data, data_length, 0, &face);
-	if (error != 0)
-	{
-		Log::Message(Log::LT_ERROR, "FreeType error %d while loading face from %s.", error, source.CString());
-		if (local_data)
-			delete[] data;
-
-		return NULL;
-	}
-
-	// Initialise the character mapping on the face.
-	if (face->charmap == NULL)
-	{
-		FT_Select_Charmap(face, FT_ENCODING_APPLE_ROMAN);
-		if (face->charmap == NULL)
-		{
-			Log::Message(Log::LT_ERROR, "Font face (from %s) does not contain a Unicode or Apple Roman character map.", source.CString());
-			FT_Done_Face(face);
-			if (local_data)
-				delete[] data;
-
-			return NULL;
-		}
-	}
-
-	return face;
+    for(FontProviderTable::iterator i = instance->font_provider_table.begin(); i != instance->font_provider_table.end(); ++i)
+    {
+        if(*i == provider)
+        {
+            instance->font_provider_table.erase(i);
+            return;
+        }
+    }
 }
 }
 
 
 }
 }

+ 2 - 95
Source/Core/FontFace.cpp

@@ -26,16 +26,15 @@
  */
  */
 
 
 #include "precompiled.h"
 #include "precompiled.h"
-#include "FontFace.h"
+#include "../../Include/Rocket/Core/FontFace.h"
 #include "FontFaceHandle.h"
 #include "FontFaceHandle.h"
 #include "../../Include/Rocket/Core/Log.h"
 #include "../../Include/Rocket/Core/Log.h"
 
 
 namespace Rocket {
 namespace Rocket {
 namespace Core {
 namespace Core {
 
 
-FontFace::FontFace(FT_Face _face, Font::Style _style, Font::Weight _weight, bool _release_stream)
+FontFace::FontFace(Font::Style _style, Font::Weight _weight, bool _release_stream)
 {
 {
-	face = _face;
 	style = _style;
 	style = _style;
 	weight = _weight;
 	weight = _weight;
 
 
@@ -50,8 +49,6 @@ FontFace::~FontFace()
 		for (size_t i = 0; i < handle_list.size(); ++i)
 		for (size_t i = 0; i < handle_list.size(); ++i)
 			handle_list[i]->RemoveReference();
 			handle_list[i]->RemoveReference();
 	}
 	}
-
-	ReleaseFace();
 }
 }
 
 
 // Returns the style of the font face.
 // Returns the style of the font face.
@@ -66,95 +63,5 @@ Font::Weight FontFace::GetWeight() const
 	return weight;
 	return weight;
 }
 }
 
 
-// Returns a handle for positioning and rendering this face at the given size.
-FontFaceHandle* FontFace::GetHandle(const String& _raw_charset, int size)
-{
-	UnicodeRangeList charset;
-
-	HandleMap::iterator iterator = handles.find(size);
-	if (iterator != handles.end())
-	{
-		const HandleList& handles = (*iterator).second;
-
-		// Check all the handles if their charsets match the requested one exactly (ie, were specified by the same
-		// string).
-		String raw_charset(_raw_charset);
-		for (size_t i = 0; i < handles.size(); ++i)
-		{
-			if (handles[i]->GetRawCharset() == _raw_charset)
-			{
-				handles[i]->AddReference();
-				return handles[i];
-			}
-		}
-
-		// Check all the handles if their charsets contain the requested charset.
-		if (!UnicodeRange::BuildList(charset, raw_charset))
-		{
-			Log::Message(Log::LT_ERROR, "Invalid font charset '%s'.", _raw_charset.CString());
-			return NULL;
-		}
-
-		for (size_t i = 0; i < handles.size(); ++i)
-		{
-			bool range_contained = true;
-
-			const UnicodeRangeList& handle_charset = handles[i]->GetCharset();
-			for (size_t j = 0; j < charset.size() && range_contained; ++j)
-			{
-				if (!charset[j].IsContained(handle_charset))
-					range_contained = false;
-			}
-
-			if (range_contained)
-			{
-				handles[i]->AddReference();
-				return handles[i];
-			}
-		}
-	}
-
-	// See if this face has been released.
-	if (face == NULL)
-	{
-		Log::Message(Log::LT_WARNING, "Font face has been released, unable to generate new handle.");
-		return NULL;
-	}
-
-	// Construct and initialise the new handle.
-	FontFaceHandle* handle = new FontFaceHandle();
-	if (!handle->Initialise(face, _raw_charset, size))
-	{
-		handle->RemoveReference();
-		return NULL;
-	}
-
-	// Save the handle, and add a reference for the callee. The initial reference will be removed when the font face
-	// releases it.
-	if (iterator != handles.end())
-		(*iterator).second.push_back(handle);
-	else
-		handles[size] = HandleList(1, handle);
-
-	handle->AddReference();
-
-	return handle;
-}
-
-// Releases the face's FreeType face structure.
-void FontFace::ReleaseFace()
-{
-	if (face != NULL)
-	{
-		FT_Byte* face_memory = face->stream->base;
-		FT_Done_Face(face);
-
-		if (release_stream)
-			delete[] face_memory;
-
-		face = NULL;
-	}
-}
-
 }
 }
 }
 }

+ 0 - 209
Source/Core/FontFaceHandle.cpp

@@ -55,8 +55,6 @@ FontFaceHandle::FontFaceHandle()
 	underline_position = 0;
 	underline_position = 0;
 	underline_thickness = 0;
 	underline_thickness = 0;
 
 
-	ft_face = NULL;
-
 	base_layer = NULL;
 	base_layer = NULL;
 }
 }
 
 
@@ -69,50 +67,6 @@ FontFaceHandle::~FontFaceHandle()
 		delete i->second;
 		delete i->second;
 }
 }
 
 
-// Initialises the handle so it is able to render text.
-bool FontFaceHandle::Initialise(FT_Face ft_face, const String& _charset, int _size)
-{
-	size = _size;
-
-	raw_charset = _charset;
-	if (!UnicodeRange::BuildList(charset, raw_charset))
-	{
-		Log::Message(Log::LT_ERROR, "Invalid font charset '%s'.", raw_charset.CString());
-		return false;
-	}
-
-	// Set the character size on the font face.
-	FT_Error error = FT_Set_Char_Size(ft_face, 0, size << 6, 0, 0);
-	if (error != 0)
-	{
-		Log::Message(Log::LT_ERROR, "Unable to set the character size '%d' on the font face '%s %s'.", size, ft_face->family_name, ft_face->style_name);
-		return false;
-	}
-
-	this->ft_face = ft_face;
-
-	// find the maximum character we are interested in
-	max_codepoint = 0;
-	for (size_t i = 0; i < charset.size(); ++i)
-		max_codepoint = Math::Max(max_codepoint, charset[i].max_codepoint);
-
-	// Construct the list of the characters specified by the charset.
-	glyphs.resize(max_codepoint+1, FontGlyph());
-	for (size_t i = 0; i < charset.size(); ++i)
-		BuildGlyphMap(charset[i]);
-
-	// Generate the metrics for the handle.
-	GenerateMetrics();
-
-	// Generate the default layer and layer configuration.
-	base_layer = GenerateLayer(NULL);
-	layer_configurations.push_back(LayerConfiguration());
-	layer_configurations.back().push_back(base_layer);
-
-
-	return true;
-}
-
 // Returns the point size of this font face.
 // Returns the point size of this font face.
 int FontFaceHandle::GetSize() const
 int FontFaceHandle::GetSize() const
 {
 {
@@ -353,169 +307,6 @@ void FontFaceHandle::OnReferenceDeactivate()
 	delete this;
 	delete this;
 }
 }
 
 
-void FontFaceHandle::GenerateMetrics()
-{
-	line_height = ft_face->size->metrics.height >> 6;
-	baseline = line_height - (ft_face->size->metrics.ascender >> 6);
-
-	underline_position = FT_MulFix(ft_face->underline_position, ft_face->size->metrics.y_scale) / float(1 << 6);
-	underline_thickness = FT_MulFix(ft_face->underline_thickness, ft_face->size->metrics.y_scale) / float(1 << 6);
-	underline_thickness = Math::Max(underline_thickness, 1.0f);
-
-	average_advance = 0;
-	unsigned int num_visible_glyphs = 0;
-	for (FontGlyphList::iterator i = glyphs.begin(); i != glyphs.end(); ++i)
-	{
-		if (i->advance)
-		{
-			average_advance += i->advance;
-			num_visible_glyphs++;
-		}
-	}
-
-	// Bring the total advance down to the average advance, but scaled up 10%, just to be on the safe side.
-	if (num_visible_glyphs)
-		average_advance = Math::RealToInteger((float) average_advance / (num_visible_glyphs * 0.9f));
-
-	// Determine the x-height of this font face.
-	word x = (word) 'x';
-	int index = FT_Get_Char_Index(ft_face, x);
-	if (FT_Load_Glyph(ft_face, index, 0) == 0)
-		x_height = ft_face->glyph->metrics.height >> 6;
-	else
-		x_height = 0;
-}
-
-void FontFaceHandle::BuildGlyphMap(const UnicodeRange& unicode_range)
-{
-	for (word character_code = (word) (Math::Max< unsigned int >(unicode_range.min_codepoint, 32)); character_code <= unicode_range.max_codepoint; ++character_code)
-	{
-		int index = FT_Get_Char_Index(ft_face, character_code);
-		if (index != 0)
-		{
-			FT_Error error = FT_Load_Glyph(ft_face, index, 0);
-			if (error != 0)
-			{
-				Log::Message(Log::LT_WARNING, "Unable to load glyph for character '%u' on the font face '%s %s'; error code: %d.", character_code, ft_face->family_name, ft_face->style_name, error);
-				continue;
-			}
-
-			error = FT_Render_Glyph(ft_face->glyph, FT_RENDER_MODE_NORMAL);
-			if (error != 0)
-			{
-				Log::Message(Log::LT_WARNING, "Unable to render glyph for character '%u' on the font face '%s %s'; error code: %d.", character_code, ft_face->family_name, ft_face->style_name, error);
-				continue;
-			}
-
-			FontGlyph glyph;
-			glyph.character = character_code;
-			BuildGlyph(glyph, ft_face->glyph);
-			glyphs[character_code] = glyph;
-		}
-	}
-}
-
-void FontFaceHandle::BuildGlyph(FontGlyph& glyph, FT_GlyphSlot ft_glyph)
-{
-	// Set the glyph's dimensions.
-	glyph.dimensions.x = ft_glyph->metrics.width >> 6;
-	glyph.dimensions.y = ft_glyph->metrics.height >> 6;
-
-	// Set the glyph's bearing.
-	glyph.bearing.x = ft_glyph->metrics.horiBearingX >> 6;
-	glyph.bearing.y = ft_glyph->metrics.horiBearingY >> 6;
-
-	// Set the glyph's advance.
-	glyph.advance = ft_glyph->metrics.horiAdvance >> 6;
-
-	// Set the glyph's bitmap dimensions.
-	glyph.bitmap_dimensions.x = ft_glyph->bitmap.width;
-	glyph.bitmap_dimensions.y = ft_glyph->bitmap.rows;
-
-	// Copy the glyph's bitmap data from the FreeType glyph handle to our glyph handle.
-	if (glyph.bitmap_dimensions.x * glyph.bitmap_dimensions.y != 0)
-	{
-		// Check the pixel mode is supported.
-		if (ft_glyph->bitmap.pixel_mode != FT_PIXEL_MODE_MONO &&
-			ft_glyph->bitmap.pixel_mode != FT_PIXEL_MODE_GRAY)
-		{
-			glyph.bitmap_data = NULL;
-			Log::Message(Log::LT_WARNING, "Unable to render glyph on the font face '%s %s'; unsupported pixel mode (%d).", ft_glyph->face->family_name, ft_glyph->face->style_name, ft_glyph->bitmap.pixel_mode);
-		}
-		else
-		{
-			glyph.bitmap_data = new byte[glyph.bitmap_dimensions.x * glyph.bitmap_dimensions.y];
-
-			byte* source_bitmap = ft_glyph->bitmap.buffer;
-			byte* destination_bitmap = glyph.bitmap_data;
-
-			// Copy the bitmap data into the newly-allocated space on our glyph.
-			switch (ft_glyph->bitmap.pixel_mode)
-			{
-				// Unpack 1-bit data into 8-bit.
-				case FT_PIXEL_MODE_MONO:
-				{
-					for (int i = 0; i < glyph.bitmap_dimensions.y; ++i)
-					{
-						int mask = 0x80;
-						byte* source_byte = source_bitmap;
-						for (int j = 0; j < glyph.bitmap_dimensions.x; ++j)
-						{
-							if ((*source_byte & mask) == mask)
-								destination_bitmap[j] = 255;
-							else
-								destination_bitmap[j] = 0;
-
-							mask >>= 1;
-							if (mask <= 0)
-							{
-								mask = 0x80;
-								++source_byte;
-							}
-						}
-
-						destination_bitmap += glyph.bitmap_dimensions.x;
-						source_bitmap += ft_glyph->bitmap.pitch;
-					}
-				}
-				break;
-
-				// Directly copy 8-bit data.
-				case FT_PIXEL_MODE_GRAY:
-				{
-					for (int i = 0; i < glyph.bitmap_dimensions.y; ++i)
-					{
-						memcpy(destination_bitmap, source_bitmap, glyph.bitmap_dimensions.x);
-						destination_bitmap += glyph.bitmap_dimensions.x;
-						source_bitmap += ft_glyph->bitmap.pitch;
-					}
-				}
-				break;
-			}
-		}
-	}
-	else
-		glyph.bitmap_data = NULL;
-}
-
-int FontFaceHandle::GetKerning(word lhs, word rhs) const
-{
-	if (!FT_HAS_KERNING(ft_face))
-		return 0;
-
-	FT_Vector ft_kerning;
-
-	FT_Error ft_error = FT_Get_Kerning(ft_face, 
-		FT_Get_Char_Index(ft_face, lhs), FT_Get_Char_Index(ft_face, rhs),
-		FT_KERNING_DEFAULT, &ft_kerning);
-
-	if (ft_error != 0)
-		return 0;
-
-	int kerning = ft_kerning.x >> 6;
-	return kerning;
-}
-
 // Generates (or shares) a layer derived from a font effect.
 // Generates (or shares) a layer derived from a font effect.
 FontFaceLayer* FontFaceHandle::GenerateLayer(FontEffect* font_effect)
 FontFaceLayer* FontFaceHandle::GenerateLayer(FontEffect* font_effect)
 {
 {

+ 7 - 26
Source/Core/FontFaceHandle.h

@@ -36,8 +36,6 @@
 #include "../../Include/Rocket/Core/Geometry.h"
 #include "../../Include/Rocket/Core/Geometry.h"
 #include "../../Include/Rocket/Core/String.h"
 #include "../../Include/Rocket/Core/String.h"
 #include "../../Include/Rocket/Core/Texture.h"
 #include "../../Include/Rocket/Core/Texture.h"
-#include <ft2build.h>
-#include FT_FREETYPE_H
 
 
 namespace Rocket {
 namespace Rocket {
 namespace Core {
 namespace Core {
@@ -54,13 +52,6 @@ public:
 	FontFaceHandle();
 	FontFaceHandle();
 	virtual ~FontFaceHandle();
 	virtual ~FontFaceHandle();
 
 
-	/// Initialises the handle so it is able to render text.
-	/// @param[in] ft_face The FreeType face that this handle is rendering.
-	/// @param[in] charset The comma-separated list of unicode ranges this handle must support.
-	/// @param[in] size The size, in points, of the face this handle should render at.
-	/// @return True if the handle initialised successfully and is ready for rendering, false if an error occured.
-	bool Initialise(FT_Face ft_face, const String& charset, int size);
-
 	/// Returns the average advance of all glyphs in this font face.
 	/// Returns the average advance of all glyphs in this font face.
 	/// @return An approximate width of the characters in this font face.
 	/// @return An approximate width of the characters in this font face.
 	int GetCharacterWidth() const;
 	int GetCharacterWidth() const;
@@ -87,18 +78,18 @@ public:
 	/// @param[in] string The string to measure.
 	/// @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.
 	/// @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.
 	/// @return The width, in pixels, this string will occupy if rendered with this handle.
-	int GetStringWidth(const WString& string, word prior_character = 0) const;
+	virtual int GetStringWidth(const WString& string, word prior_character = 0) const = 0;
 
 
 	/// Generates, if required, the layer configuration for a given array of font effects.
 	/// Generates, if required, the layer configuration for a given array of font effects.
 	/// @param[in] font_effects The list of font effects to generate the configuration for.
 	/// @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.
 	/// @return The index to use when generating geometry using this configuration.
-	int GenerateLayerConfiguration(FontEffectMap& font_effects);
+	virtual int GenerateLayerConfiguration(FontEffectMap& font_effects) = 0;
 	/// Generates the texture data for a layer (for the texture database).
 	/// 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.
 	/// @param[out] texture_data The pointer to be set to the generated texture data.
 	/// @param[out] texture_dimensions The dimensions of the texture.
 	/// @param[out] texture_dimensions The dimensions of the texture.
 	/// @param[in] layer_id The id of the layer to request the texture data from.
 	/// @param[in] layer_id The id of the layer to request the texture data from.
 	/// @param[in] texture_id The index of the texture within the layer to generate.
 	/// @param[in] texture_id The index of the texture within the layer to generate.
-	bool GenerateLayerTexture(const byte*& texture_data, Vector2i& texture_dimensions, FontEffect* layer_id, int texture_id);
+	virtual bool GenerateLayerTexture(const byte*& texture_data, Vector2i& texture_dimensions, FontEffect* layer_id, int texture_id) = 0;
 
 
 	/// Generates the geometry required to render a single line of text.
 	/// Generates the geometry required to render a single line of text.
 	/// @param[out] geometry An array of geometries to generate the geometry into.
 	/// @param[out] geometry An array of geometries to generate the geometry into.
@@ -106,14 +97,14 @@ public:
 	/// @param[in] position The position of the baseline of the first character 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.
 	/// @param[in] colour The colour to render the text.
 	/// @return The width, in pixels, of the string geometry.
 	/// @return The width, in pixels, of the string geometry.
-	int GenerateString(GeometryList& geometry, const WString& string, const Vector2f& position, const Colourb& colour, int layer_configuration = 0) const;
+	virtual int GenerateString(GeometryList& geometry, const WString& string, const Vector2f& position, const Colourb& colour, int layer_configuration = 0) const = 0;
 	/// Generates the geometry required to render a line above, below or through a line of text.
 	/// 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[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] position The position of the baseline of the lined text.
 	/// @param[in] width The width of the string to line.
 	/// @param[in] width The width of the string to line.
 	/// @param[in] height The height to render the line at.
 	/// @param[in] height The height to render the line at.
 	/// @param[in] colour The colour to draw the line in.
 	/// @param[in] colour The colour to draw the line in.
-	void GenerateLine(Geometry* geometry, const Vector2f& position, int width, Font::Line height, const Colourb& colour) const;
+	virtual void GenerateLine(Geometry* geometry, const Vector2f& position, int width, Font::Line height, const Colourb& colour) const = 0;
 
 
 	/// Returns the font face's raw charset (the charset range as a string).
 	/// Returns the font face's raw charset (the charset range as a string).
 	/// @return The font face's charset.
 	/// @return The font face's charset.
@@ -125,24 +116,14 @@ public:
 protected:
 protected:
 	/// Destroys the handle.
 	/// Destroys the handle.
 	virtual void OnReferenceDeactivate();
 	virtual void OnReferenceDeactivate();
-
-private:
-	void GenerateMetrics(void);
-
-	void BuildGlyphMap(const UnicodeRange& unicode_range);
-	void BuildGlyph(FontGlyph& glyph, FT_GlyphSlot ft_glyph);
-
-	int GetKerning(word lhs, word rhs) const;
-
-	// Generates (or shares) a layer derived from a font effect.
 	FontFaceLayer* GenerateLayer(FontEffect* font_effect);
 	FontFaceLayer* GenerateLayer(FontEffect* font_effect);
+	virtual int GetKerning(word lhs, word rhs) const = 0;
 
 
 	typedef std::vector< int > GlyphKerningList;
 	typedef std::vector< int > GlyphKerningList;
 	typedef std::vector< GlyphKerningList > FontKerningList;
 	typedef std::vector< GlyphKerningList > FontKerningList;
 
 
-	FT_Face ft_face;
-
 	FontGlyphList glyphs;
 	FontGlyphList glyphs;
+	FontKerningList kerning;
 
 
 	typedef std::map< const FontEffect*, FontFaceLayer* > FontLayerMap;
 	typedef std::map< const FontEffect*, FontFaceLayer* > FontLayerMap;
 	typedef std::map< String, FontFaceLayer* > FontLayerCache;
 	typedef std::map< String, FontFaceLayer* > FontLayerCache;

+ 3 - 3
Source/Core/FontFaceLayer.h

@@ -60,14 +60,14 @@ public:
 	/// @param[in] clone The layer to optionally clone geometry and texture data from.
 	/// @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.
 	/// @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.
 	/// @return True if the layer was generated successfully, false if not.
-	bool Initialise(const FontFaceHandle* handle, FontEffect* effect = NULL, const FontFaceLayer* clone = NULL, bool deep_clone = false);
+	virtual bool Initialise(const FontFaceHandle* handle, FontEffect* effect = NULL, const FontFaceLayer* clone = NULL, bool deep_clone = false);
 
 
 	/// Generates the texture data for a layer (for the texture database).
 	/// 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.
 	/// @param[out] texture_data The pointer to be set to the generated texture data.
 	/// @param[out] texture_dimensions The dimensions of the texture.
 	/// @param[out] texture_dimensions The dimensions of the texture.
 	/// @param[in] glyphs The glyphs required by the font face handle.
 	/// @param[in] glyphs The glyphs required by the font face handle.
 	/// @param[in] texture_id The index of the texture within the layer to generate.
 	/// @param[in] texture_id The index of the texture within the layer to generate.
-	bool GenerateTexture(const byte*& texture_data, Vector2i& texture_dimensions, int texture_id);
+	virtual bool GenerateTexture(const byte*& texture_data, Vector2i& texture_dimensions, int texture_id);
 	/// Generates the geometry required to render a single character.
 	/// Generates the geometry required to render a single character.
 	/// @param[out] geometry An array of geometries this layer will write to. It must be at least as big as the number of textures in this layer.
 	/// @param[out] geometry An array of geometries this layer will write to. It must be at least as big as the number of textures in this layer.
 	/// @param[in] character_code The character to generate geometry for.
 	/// @param[in] character_code The character to generate geometry for.
@@ -107,7 +107,7 @@ public:
 	/// @return The layer's colour.
 	/// @return The layer's colour.
 	const Colourb& GetColour() const;
 	const Colourb& GetColour() const;
 
 
-private:
+// protected:
 	struct Character
 	struct Character
 	{
 	{
 		Character() : texture_index(-1) { }
 		Character() : texture_index(-1) { }

+ 2 - 11
Source/Core/FontFamily.cpp

@@ -26,8 +26,8 @@
  */
  */
 
 
 #include "precompiled.h"
 #include "precompiled.h"
-#include "FontFamily.h"
-#include "FontFace.h"
+#include "../../Include/Rocket/Core/FontFamily.h"
+#include "../../Include/Rocket/Core/FontFace.h"
 
 
 namespace Rocket {
 namespace Rocket {
 namespace Core {
 namespace Core {
@@ -42,15 +42,6 @@ FontFamily::~FontFamily()
 		delete font_faces[i];
 		delete font_faces[i];
 }
 }
 
 
-// Adds a new face to the family.
-bool FontFamily::AddFace(FT_Face ft_face, Font::Style style, Font::Weight weight, bool release_stream)
-{
-	FontFace* face = new FontFace(ft_face, style, weight, release_stream);
-	font_faces.push_back(face);
-
-	return true;
-}
-
 // Returns a handle to the most appropriate font in the family, at the correct size.
 // Returns a handle to the most appropriate font in the family, at the correct size.
 FontFaceHandle* FontFamily::GetFaceHandle(const String& charset, Font::Style style, Font::Weight weight, int size)
 FontFaceHandle* FontFamily::GetFaceHandle(const String& charset, Font::Style style, Font::Weight weight, int size)
 {
 {

+ 45 - 0
Source/Core/FontProvider.cpp

@@ -0,0 +1,45 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * 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.
+ *
+ */
+
+#include <Rocket/Core/FontProvider.h>
+#include <Rocket/Core/FontFamily.h>
+
+namespace Rocket {
+namespace Core {
+
+// Returns a handle to a font face that can be used to position and render text.
+Rocket::Core::FontFaceHandle* FontProvider::GetFontFaceHandle(const String& family, const String& charset, Font::Style style, Font::Weight weight, int size)
+{
+	FontFamilyMap::iterator iterator = font_families.find(family);
+	if (iterator == font_families.end())
+		return NULL;
+
+	return (*iterator).second->GetFaceHandle(charset, style, weight, size);
+}
+
+}
+}

+ 139 - 0
Source/Core/FreeType/FontFace.cpp

@@ -0,0 +1,139 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * 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.
+ *
+ */
+
+#include "../precompiled.h"
+#include "FontFace.h"
+#include "FontFaceHandle.h"
+#include "../../../Include/Rocket/Core/Log.h"
+
+namespace Rocket {
+namespace Core {
+namespace FreeType {
+
+FontFace::FontFace(FT_Face _face, Font::Style _style, Font::Weight _weight, bool _release_stream) : Rocket::Core::FontFace(_style, _weight, _release_stream)
+{
+	face = _face;
+}
+
+FontFace::~FontFace()
+{
+	ReleaseFace();
+}
+
+// Returns a handle for positioning and rendering this face at the given size.
+Rocket::Core::FontFaceHandle* FontFace::GetHandle(const String& _raw_charset, int size)
+{
+	UnicodeRangeList charset;
+
+	HandleMap::iterator iterator = handles.find(size);
+	if (iterator != handles.end())
+	{
+		const HandleList& handles = (*iterator).second;
+
+		// Check all the handles if their charsets match the requested one exactly (ie, were specified by the same
+		// string).
+		String raw_charset(_raw_charset);
+		for (size_t i = 0; i < handles.size(); ++i)
+		{
+			if (handles[i]->GetRawCharset() == _raw_charset)
+			{
+				handles[i]->AddReference();
+				return (Rocket::Core::FreeType::FontFaceHandle*)handles[i];
+			}
+		}
+
+		// Check all the handles if their charsets contain the requested charset.
+		if (!UnicodeRange::BuildList(charset, raw_charset))
+		{
+			Log::Message(Log::LT_ERROR, "Invalid font charset '%s'.", _raw_charset.CString());
+			return NULL;
+		}
+
+		for (size_t i = 0; i < handles.size(); ++i)
+		{
+			bool range_contained = true;
+
+			const UnicodeRangeList& handle_charset = handles[i]->GetCharset();
+			for (size_t j = 0; j < charset.size() && range_contained; ++j)
+			{
+				if (!charset[j].IsContained(handle_charset))
+					range_contained = false;
+			}
+
+			if (range_contained)
+			{
+				handles[i]->AddReference();
+				return (Rocket::Core::FreeType::FontFaceHandle*)handles[i];
+			}
+		}
+	}
+
+	// See if this face has been released.
+	if (face == NULL)
+	{
+		Log::Message(Log::LT_WARNING, "Font face has been released, unable to generate new handle.");
+		return NULL;
+	}
+
+	// Construct and initialise the new handle.
+	FontFaceHandle* handle = new FontFaceHandle();
+	if (!handle->Initialise(face, _raw_charset, size))
+	{
+		handle->RemoveReference();
+		return NULL;
+	}
+
+	// Save the handle, and add a reference for the callee. The initial reference will be removed when the font face
+	// releases it.
+	if (iterator != handles.end())
+		(*iterator).second.push_back(handle);
+	else
+		handles[size] = HandleList(1, handle);
+
+	handle->AddReference();
+
+	return handle;
+}
+
+// Releases the face's FreeType face structure.
+void FontFace::ReleaseFace()
+{
+	if (face != NULL)
+	{
+		FT_Byte* face_memory = face->stream->base;
+		FT_Done_Face(face);
+
+		if (release_stream)
+			delete[] face_memory;
+
+		face = NULL;
+	}
+}
+
+}
+}
+}

+ 68 - 0
Source/Core/FreeType/FontFace.h

@@ -0,0 +1,68 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * 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 ROCKETCOREFREETYPEFONTFACE_H
+#define ROCKETCOREFREETYPEFONTFACE_H
+
+#include "../../../Include/Rocket/Core/FontFace.h"
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+namespace Rocket {
+namespace Core {
+namespace FreeType {
+/**
+	@author Peter Curry
+ */
+
+class FontFaceHandle;
+
+class FontFace : public Rocket::Core::FontFace
+{
+public:
+	FontFace(FT_Face face, Font::Style style, Font::Weight weight, bool release_stream);
+	~FontFace();
+
+	/// Returns a handle for positioning and rendering this face at the given size.
+	/// @param[in] charset The set of characters in the handle, as a comma-separated list of unicode ranges.
+	/// @param[in] size The size of the desired handle, in points.
+	/// @return The shared font handle.
+	Rocket::Core::FontFaceHandle* GetHandle(const String& charset, int size);
+
+	/// Releases the face's FreeType face structure. This will mean handles for new sizes cannot be constructed,
+	/// but existing ones can still be fetched.
+	void ReleaseFace();
+
+private:
+	FT_Face face;
+};
+
+}
+}
+}
+
+#endif

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

@@ -0,0 +1,458 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * 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.
+ *
+ */
+
+#include "../precompiled.h"
+#include "FontFaceHandle.h"
+#include <algorithm>
+#include "../../../Include/Rocket/Core.h"
+#include "../FontFaceLayer.h"
+#include "../TextureLayout.h"
+
+namespace Rocket {
+namespace Core {
+namespace FreeType {
+
+class FontEffectSort
+{
+public:
+	bool operator()(const FontEffect* lhs, const FontEffect* rhs)
+	{
+		return lhs->GetZIndex() < rhs->GetZIndex();
+	}
+};
+
+FontFaceHandle::FontFaceHandle()
+{
+	ft_face = NULL;
+}
+
+FontFaceHandle::~FontFaceHandle()
+{
+}
+
+// Initialises the handle so it is able to render text.
+bool FontFaceHandle::Initialise(FT_Face ft_face, const String& _charset, int _size)
+{
+	size = _size;
+
+	raw_charset = _charset;
+	if (!UnicodeRange::BuildList(charset, raw_charset))
+	{
+		Log::Message(Log::LT_ERROR, "Invalid font charset '%s'.", raw_charset.CString());
+		return false;
+	}
+
+	// Set the character size on the font face.
+	FT_Error error = FT_Set_Char_Size(ft_face, 0, size << 6, 0, 0);
+	if (error != 0)
+	{
+		Log::Message(Log::LT_ERROR, "Unable to set the character size '%d' on the font face '%s %s'.", size, ft_face->family_name, ft_face->style_name);
+		return false;
+	}
+
+	this->ft_face = ft_face;
+
+	// find the maximum character we are interested in
+	max_codepoint = 0;
+	for (size_t i = 0; i < charset.size(); ++i)
+		max_codepoint = Math::Max(max_codepoint, charset[i].max_codepoint);
+
+	// Construct the list of the characters specified by the charset.
+	glyphs.resize(max_codepoint+1, FontGlyph());
+	for (size_t i = 0; i < charset.size(); ++i)
+		BuildGlyphMap(charset[i]);
+
+	// Generate the metrics for the handle.
+	GenerateMetrics();
+
+	// Generate the default layer and layer configuration.
+	base_layer = GenerateLayer(NULL);
+	layer_configurations.push_back(LayerConfiguration());
+	layer_configurations.back().push_back(base_layer);
+
+
+	return true;
+}
+
+// Returns the width a string will take up if rendered with this handle.
+int FontFaceHandle::GetStringWidth(const WString& string, word prior_character) const
+{
+	int width = 0;
+
+	for (size_t i = 0; i < string.Length(); i++)
+	{
+		word character_code = string[i];
+
+		if (character_code >= glyphs.size())
+			continue;
+		const FontGlyph &glyph = glyphs[character_code];
+
+		// Adjust the cursor for the kerning between this character and the previous one.
+		if (prior_character != 0)
+			width += GetKerning(prior_character, string[i]);
+		// Adjust the cursor for this character's advance.
+		width += glyph.advance;
+
+		prior_character = character_code;
+	}
+
+	return width;
+}
+
+// Generates, if required, the layer configuration for a given array of font effects.
+int FontFaceHandle::GenerateLayerConfiguration(FontEffectMap& font_effects)
+{
+	if (font_effects.empty())
+		return 0;
+
+	// Prepare a list of effects, sorted by z-index.
+	FontEffectList sorted_effects;
+	for (FontEffectMap::const_iterator i = font_effects.begin(); i != font_effects.end(); ++i)
+		sorted_effects.push_back(i->second);
+
+	std::sort(sorted_effects.begin(), sorted_effects.end(), FontEffectSort());
+
+	// Check each existing configuration for a match with this arrangement of effects.
+	int configuration_index = 1;
+	for (; configuration_index < (int) layer_configurations.size(); ++configuration_index)
+	{
+		const LayerConfiguration& configuration = layer_configurations[configuration_index];
+
+		// Check the size is correct. For a math, there should be one layer in the configuration
+		// plus an extra for the base layer.
+		if (configuration.size() != sorted_effects.size() + 1)
+			continue;
+
+		// Check through each layer, checking it was created by the same effect as the one we're
+		// checking.
+		size_t effect_index = 0;
+		for (size_t i = 0; i < configuration.size(); ++i)
+		{
+			// Skip the base layer ...
+			if (configuration[i]->GetFontEffect() == NULL)
+				continue;
+
+			// If the ith layer's effect doesn't match the equivalent effect, then this
+			// configuration can't match.
+			if (configuration[i]->GetFontEffect() != sorted_effects[effect_index])
+				break;
+
+			// Check the next one ...
+			++effect_index;
+		}
+
+		if (effect_index == sorted_effects.size())
+			return configuration_index;
+	}
+
+	// No match, so we have to generate a new layer configuration.
+	layer_configurations.push_back(LayerConfiguration());
+	LayerConfiguration& layer_configuration = layer_configurations.back();
+
+	bool added_base_layer = false;
+
+	for (size_t i = 0; i < sorted_effects.size(); ++i)
+	{
+		if (!added_base_layer &&
+			sorted_effects[i]->GetZIndex() >= 0)
+		{
+			layer_configuration.push_back(base_layer);
+			added_base_layer = true;
+		}
+
+		layer_configuration.push_back(GenerateLayer(sorted_effects[i]));
+	}
+
+	// Add the base layer now if we still haven't added it.
+	if (!added_base_layer)
+		layer_configuration.push_back(base_layer);
+
+	return (int) (layer_configurations.size() - 1);
+}
+
+// Generates the texture data for a layer (for the texture database).
+bool FontFaceHandle::GenerateLayerTexture(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())
+		return false;
+
+	return layer_iterator->second->GenerateTexture(texture_data, texture_dimensions, texture_id);
+}
+
+// Generates the geometry required to render a single line of text.
+int FontFaceHandle::GenerateString(GeometryList& geometry, const WString& string, const Vector2f& position, const Colourb& colour, int layer_configuration_index) const
+{
+	int geometry_index = 0;
+	int line_width = 0;
+
+	ROCKET_ASSERT(layer_configuration_index >= 0);
+	ROCKET_ASSERT(layer_configuration_index < (int) layer_configurations.size());
+
+	// Fetch the requested configuration and generate the geometry for each one.
+	const LayerConfiguration& layer_configuration = layer_configurations[layer_configuration_index];
+	for (size_t i = 0; i < layer_configuration.size(); ++i)
+	{
+		FontFaceLayer* layer = layer_configuration[i];
+
+		Colourb layer_colour;
+		if (layer == base_layer)
+			layer_colour = colour;
+		else
+			layer_colour = layer->GetColour();
+
+		// Resize the geometry list if required.
+		if ((int) geometry.size() < geometry_index + layer->GetNumTextures())
+			geometry.resize(geometry_index + layer->GetNumTextures());
+
+		// Bind the textures to the geometries.
+		for (int i = 0; i < layer->GetNumTextures(); ++i)
+			geometry[geometry_index + i].SetTexture(layer->GetTexture(i));
+
+		line_width = 0;
+		word prior_character = 0;
+
+		const word* string_iterator = string.CString();
+		const word* string_end = string.CString() + string.Length();
+
+		for (; string_iterator != string_end; string_iterator++)
+		{
+			if (*string_iterator >= glyphs.size())
+				continue;
+			const FontGlyph &glyph = glyphs[*string_iterator];
+
+			// Adjust the cursor for the kerning between this character and the previous one.
+			if (prior_character != 0)
+				line_width += GetKerning(prior_character, *string_iterator);
+
+			layer->GenerateGeometry(&geometry[geometry_index], *string_iterator, Vector2f(position.x + line_width, position.y), layer_colour);
+
+			line_width += glyph.advance;
+			prior_character = *string_iterator;
+		}
+
+		geometry_index += layer->GetNumTextures();
+	}
+
+	// Cull any excess geometry from a previous generation.
+	geometry.resize(geometry_index);
+
+	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, Font::Line height, const Colourb& colour) const
+{
+	std::vector< Vertex >& line_vertices = geometry->GetVertices();
+	std::vector< int >& line_indices = geometry->GetIndices();
+
+	float offset;
+	switch (height)
+	{
+		case Font::UNDERLINE:			offset = -underline_position; break;
+		case Font::OVERLINE:			// where to place? offset = -line_height - underline_position; break;
+		case Font::STRIKE_THROUGH:		// where to place? offset = -line_height * 0.5f; break;
+		default:						return;
+	}
+
+	line_vertices.resize(line_vertices.size() + 4);
+	line_indices.resize(line_indices.size() + 6);
+	GeometryUtilities::GenerateQuad(&line_vertices[0] + (line_vertices.size() - 4), &line_indices[0] + (line_indices.size() - 6), Vector2f(position.x, position.y + offset), Vector2f((float) width, underline_thickness), colour, (int)line_vertices.size() - 4);
+}
+
+// Destroys the handle.
+void FontFaceHandle::OnReferenceDeactivate()
+{
+	delete this;
+}
+
+void FontFaceHandle::GenerateMetrics()
+{
+	line_height = ft_face->size->metrics.height >> 6;
+	baseline = line_height - (ft_face->size->metrics.ascender >> 6);
+
+	underline_position = FT_MulFix(ft_face->underline_position, ft_face->size->metrics.y_scale) / float(1 << 6);
+	underline_thickness = FT_MulFix(ft_face->underline_thickness, ft_face->size->metrics.y_scale) / float(1 << 6);
+	underline_thickness = Math::Max(underline_thickness, 1.0f);
+
+	average_advance = 0;
+	unsigned int num_visible_glyphs = 0;
+	for (FontGlyphList::iterator i = glyphs.begin(); i != glyphs.end(); ++i)
+	{
+		if (i->advance)
+		{
+			average_advance += i->advance;
+			num_visible_glyphs++;
+		}
+	}
+
+	// Bring the total advance down to the average advance, but scaled up 10%, just to be on the safe side.
+	if (num_visible_glyphs)
+		average_advance = Math::RealToInteger((float) average_advance / (num_visible_glyphs * 0.9f));
+
+	// Determine the x-height of this font face.
+	word x = (word) 'x';
+	int index = FT_Get_Char_Index(ft_face, x);
+	if (FT_Load_Glyph(ft_face, index, 0) == 0)
+		x_height = ft_face->glyph->metrics.height >> 6;
+	else
+		x_height = 0;
+}
+
+void FontFaceHandle::BuildGlyphMap(const UnicodeRange& unicode_range)
+{
+	for (word character_code = (word) (Math::Max< unsigned int >(unicode_range.min_codepoint, 32)); character_code <= unicode_range.max_codepoint; ++character_code)
+	{
+		int index = FT_Get_Char_Index(ft_face, character_code);
+		if (index != 0)
+		{
+			FT_Error error = FT_Load_Glyph(ft_face, index, 0);
+			if (error != 0)
+			{
+				Log::Message(Log::LT_WARNING, "Unable to load glyph for character '%u' on the font face '%s %s'; error code: %d.", character_code, ft_face->family_name, ft_face->style_name, error);
+				continue;
+			}
+
+			error = FT_Render_Glyph(ft_face->glyph, FT_RENDER_MODE_NORMAL);
+			if (error != 0)
+			{
+				Log::Message(Log::LT_WARNING, "Unable to render glyph for character '%u' on the font face '%s %s'; error code: %d.", character_code, ft_face->family_name, ft_face->style_name, error);
+				continue;
+			}
+
+			FontGlyph glyph;
+			glyph.character = character_code;
+			BuildGlyph(glyph, ft_face->glyph);
+			glyphs[character_code] = glyph;
+		}
+	}
+}
+
+void FontFaceHandle::BuildGlyph(FontGlyph& glyph, FT_GlyphSlot ft_glyph)
+{
+	// Set the glyph's dimensions.
+	glyph.dimensions.x = ft_glyph->metrics.width >> 6;
+	glyph.dimensions.y = ft_glyph->metrics.height >> 6;
+
+	// Set the glyph's bearing.
+	glyph.bearing.x = ft_glyph->metrics.horiBearingX >> 6;
+	glyph.bearing.y = ft_glyph->metrics.horiBearingY >> 6;
+
+	// Set the glyph's advance.
+	glyph.advance = ft_glyph->metrics.horiAdvance >> 6;
+
+	// Set the glyph's bitmap dimensions.
+	glyph.bitmap_dimensions.x = ft_glyph->bitmap.width;
+	glyph.bitmap_dimensions.y = ft_glyph->bitmap.rows;
+
+	// Copy the glyph's bitmap data from the FreeType glyph handle to our glyph handle.
+	if (glyph.bitmap_dimensions.x * glyph.bitmap_dimensions.y != 0)
+	{
+		// Check the pixel mode is supported.
+		if (ft_glyph->bitmap.pixel_mode != FT_PIXEL_MODE_MONO &&
+			ft_glyph->bitmap.pixel_mode != FT_PIXEL_MODE_GRAY)
+		{
+			glyph.bitmap_data = NULL;
+			Log::Message(Log::LT_WARNING, "Unable to render glyph on the font face '%s %s'; unsupported pixel mode (%d).", ft_glyph->face->family_name, ft_glyph->face->style_name, ft_glyph->bitmap.pixel_mode);
+		}
+		else
+		{
+			glyph.bitmap_data = new byte[glyph.bitmap_dimensions.x * glyph.bitmap_dimensions.y];
+
+			byte* source_bitmap = ft_glyph->bitmap.buffer;
+			byte* destination_bitmap = glyph.bitmap_data;
+
+			// Copy the bitmap data into the newly-allocated space on our glyph.
+			switch (ft_glyph->bitmap.pixel_mode)
+			{
+				// Unpack 1-bit data into 8-bit.
+				case FT_PIXEL_MODE_MONO:
+				{
+					for (int i = 0; i < glyph.bitmap_dimensions.y; ++i)
+					{
+						int mask = 0x80;
+						byte* source_byte = source_bitmap;
+						for (int j = 0; j < glyph.bitmap_dimensions.x; ++j)
+						{
+							if ((*source_byte & mask) == mask)
+								destination_bitmap[j] = 255;
+							else
+								destination_bitmap[j] = 0;
+
+							mask >>= 1;
+							if (mask <= 0)
+							{
+								mask = 0x80;
+								++source_byte;
+							}
+						}
+
+						destination_bitmap += glyph.bitmap_dimensions.x;
+						source_bitmap += ft_glyph->bitmap.pitch;
+					}
+				}
+				break;
+
+				// Directly copy 8-bit data.
+				case FT_PIXEL_MODE_GRAY:
+				{
+					for (int i = 0; i < glyph.bitmap_dimensions.y; ++i)
+					{
+						memcpy(destination_bitmap, source_bitmap, glyph.bitmap_dimensions.x);
+						destination_bitmap += glyph.bitmap_dimensions.x;
+						source_bitmap += ft_glyph->bitmap.pitch;
+					}
+				}
+				break;
+			}
+		}
+	}
+	else
+		glyph.bitmap_data = NULL;
+}
+
+int FontFaceHandle::GetKerning(word lhs, word rhs) const
+{
+	if (!FT_HAS_KERNING(ft_face))
+		return 0;
+
+	FT_Vector ft_kerning;
+
+	FT_Error ft_error = FT_Get_Kerning(ft_face,
+		FT_Get_Char_Index(ft_face, lhs), FT_Get_Char_Index(ft_face, rhs),
+		FT_KERNING_DEFAULT, &ft_kerning);
+
+	if (ft_error != 0)
+		return 0;
+
+	int kerning = ft_kerning.x >> 6;
+	return kerning;
+}
+
+}
+}
+}

+ 117 - 0
Source/Core/FreeType/FontFaceHandle.h

@@ -0,0 +1,117 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * 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 ROCKETCOREFREETYPEFONTFACEHANDLE_H
+#define ROCKETCOREFREETYPEFONTFACEHANDLE_H
+
+#include "../../../Include/Rocket/Core/ReferenceCountable.h"
+#include "../UnicodeRange.h"
+#include "../FontFaceHandle.h"
+#include "../../../Include/Rocket/Core/FontEffect.h"
+#include "../../../Include/Rocket/Core/FontGlyph.h"
+#include "../../../Include/Rocket/Core/Geometry.h"
+#include "../../../Include/Rocket/Core/String.h"
+#include "../../../Include/Rocket/Core/Texture.h"
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+namespace Rocket {
+namespace Core {
+
+class FontFaceLayer;
+
+namespace FreeType {
+
+/**
+	@author Peter Curry
+ */
+
+class FontFaceHandle : public Rocket::Core::FontFaceHandle
+{
+public:
+	FontFaceHandle();
+	virtual ~FontFaceHandle();
+
+	/// Initialises the handle so it is able to render text.
+	/// @param[in] ft_face The FreeType face that this handle is rendering.
+	/// @param[in] charset The comma-separated list of unicode ranges this handle must support.
+	/// @param[in] size The size, in points, of the face this handle should render at.
+	/// @return True if the handle initialised successfully and is ready for rendering, false if an error occured.
+	bool Initialise(FT_Face ft_face, const String& charset, int size);
+
+	/// Returns the width a string will take up if rendered with this handle.
+	/// @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.
+	int GetStringWidth(const WString& string, word prior_character = 0) const;
+
+	/// Generates, if required, the layer configuration for a given array of font effects.
+	/// @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.
+	int GenerateLayerConfiguration(FontEffectMap& font_effects);
+	/// 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.
+	/// @param[out] texture_dimensions The dimensions of the texture.
+	/// @param[in] layer_id The id of the layer to request the texture data from.
+	/// @param[in] texture_id The index of the texture within the layer to generate.
+	bool GenerateLayerTexture(const byte*& texture_data, Vector2i& texture_dimensions, FontEffect* layer_id, int texture_id);
+
+	/// 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] 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.
+	int GenerateString(GeometryList& geometry, const WString& string, const Vector2f& position, const Colourb& colour, int layer_configuration = 0) const;
+	/// 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] height The height to render the line at.
+	/// @param[in] colour The colour to draw the line in.
+	void GenerateLine(Geometry* geometry, const Vector2f& position, int width, Font::Line height, const Colourb& colour) const;
+
+protected:
+	/// Destroys the handle.
+	virtual void OnReferenceDeactivate();
+
+	int GetKerning(word lhs, word rhs) const;
+
+private:
+	void GenerateMetrics(void);
+
+	void BuildGlyphMap(const UnicodeRange& unicode_range);
+	void BuildGlyph(FontGlyph& glyph, FT_GlyphSlot ft_glyph);
+
+	FT_Face ft_face;
+};
+
+}
+}
+}
+
+#endif

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

@@ -0,0 +1,58 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * 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.
+ *
+ */
+
+#include "../precompiled.h"
+#include "FontFamily.h"
+#include "FontFace.h"
+
+namespace Rocket {
+namespace Core {
+namespace FreeType
+{
+
+FontFamily::FontFamily(const String& name) : Rocket::Core::FontFamily(name)
+{
+
+}
+
+FontFamily::~FontFamily()
+{
+
+}
+
+// Adds a new face to the family.
+bool FontFamily::AddFace(void* ft_face, Font::Style style, Font::Weight weight, bool release_stream)
+{
+	FontFace* face = new FontFace((FT_Face)ft_face, style, weight, release_stream);
+	font_faces.push_back(face);
+
+	return true;
+}
+
+}
+}
+}

+ 67 - 0
Source/Core/FreeType/FontFamily.h

@@ -0,0 +1,67 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * 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 ROCKETCOREFREETYPEFONTFAMILY_H
+#define ROCKETCOREFREETYPEFONTFAMILY_H
+
+#include <Rocket/Core/Font.h>
+#include <Rocket/Core/FontFamily.h>
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+namespace Rocket {
+namespace Core {
+
+class FontFace;
+class FontFaceHandle;
+
+/**
+	@author Peter Curry
+ */
+
+namespace FreeType {
+
+class FontFamily : public Rocket::Core::FontFamily
+{
+public:
+	FontFamily(const String& name);
+	~FontFamily();
+
+	/// Adds a new face to the family.
+	/// @param[in] ft_face The previously loaded FreeType face.
+	/// @param[in] style The style of the new face.
+	/// @param[in] weight The weight of the new face.
+	/// @param[in] release_stream True if the application must free the face's memory stream.
+	/// @return True if the face was loaded successfully, false otherwise.
+	bool AddFace(void* ft_face, Font::Style style, Font::Weight weight, bool release_stream);
+};
+
+}
+}
+}
+
+#endif

+ 258 - 0
Source/Core/FreeType/FontProvider.cpp

@@ -0,0 +1,258 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * 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.
+ *
+ */
+
+#include "../precompiled.h"
+#include <Rocket/Core/FreeType/FontProvider.h>
+#include "FontFaceHandle.h"
+#include <Rocket/Core/FontDatabase.h>
+#include "FontFamily.h"
+#include <Rocket/Core.h>
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+namespace Rocket {
+namespace Core {
+namespace FreeType {
+
+FontProvider* FontProvider::instance = NULL;
+
+static FT_Library ft_library = NULL;
+
+FontProvider::FontProvider()
+{
+	ROCKET_ASSERT(instance == NULL);
+	instance = this;
+}
+
+FontProvider::~FontProvider()
+{
+	ROCKET_ASSERT(instance == this);
+	instance = NULL;
+}
+
+bool FontProvider::Initialise()
+{
+	if (instance == NULL)
+	{
+		new FontProvider();
+
+		FontDatabase::AddFontProvider(instance);
+
+		FT_Error result = FT_Init_FreeType(&ft_library);
+		if (result != 0)
+		{
+			Log::Message(Log::LT_ERROR, "Failed to initialise FreeType, error %d.", result);
+			Shutdown();
+			return false;
+		}
+	}
+
+	return true;
+}
+
+void FontProvider::Shutdown()
+{
+	if (instance != NULL)
+	{
+		for (FontFamilyMap::iterator i = instance->font_families.begin(); i != instance->font_families.end(); ++i)
+			delete (*i).second;
+
+		if (ft_library != NULL)
+		{
+			FT_Done_FreeType(ft_library);
+			ft_library = NULL;
+		}
+
+		delete instance;
+	}
+}
+
+// Loads a new font face.
+bool FontProvider::LoadFontFace(const String& file_name)
+{
+	FT_Face ft_face = (FT_Face) instance->LoadFace(file_name);
+	if (ft_face == NULL)
+	{
+		Log::Message(Log::LT_ERROR, "Failed to load font face from %s.", file_name.CString());
+		return false;
+	}
+
+	Font::Style style = ft_face->style_flags & FT_STYLE_FLAG_ITALIC ? Font::STYLE_ITALIC : Font::STYLE_NORMAL;
+	Font::Weight weight = ft_face->style_flags & FT_STYLE_FLAG_BOLD ? Font::WEIGHT_BOLD : Font::WEIGHT_NORMAL;
+
+	if (instance->AddFace(ft_face, ft_face->family_name, 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.CString());
+		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.CString());
+		return false;
+	}
+}
+
+// Adds a new font face to the database, ignoring any family, style and weight information stored in the face itself.
+bool FontProvider::LoadFontFace(const String& file_name, const String& family, Font::Style style, Font::Weight weight)
+{
+	FT_Face ft_face = (FT_Face) instance->LoadFace(file_name);
+	if (ft_face == NULL)
+	{
+		Log::Message(Log::LT_ERROR, "Failed to load font face from %s.", file_name.CString());
+		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.CString());
+		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.CString());
+		return false;
+	}
+}
+
+// Adds a new font face to the database, loading from memory.
+bool FontProvider::LoadFontFace(const byte* data, int data_length)
+{
+	FT_Face ft_face = (FT_Face) instance->LoadFace(data, data_length, "memory", false);
+	if (ft_face == NULL)
+	{
+		Log::Message(Log::LT_ERROR, "Failed to load font face from byte stream.");
+		return false;
+	}
+
+	Font::Style style = ft_face->style_flags & FT_STYLE_FLAG_ITALIC ? Font::STYLE_ITALIC : Font::STYLE_NORMAL;
+	Font::Weight weight = ft_face->style_flags & FT_STYLE_FLAG_BOLD ? Font::WEIGHT_BOLD : Font::WEIGHT_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::LoadFontFace(const byte* data, int data_length, const String& family, Font::Style style, Font::Weight weight)
+{
+	FT_Face ft_face = (FT_Face) instance->LoadFace(data, data_length, "memory", false);
+	if (ft_face == NULL)
+	{
+		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::AddFace(void* face, const String& family, Font::Style style, Font::Weight weight, bool release_stream)
+{
+	FontFamily* font_family = NULL;
+	FontFamilyMap::iterator iterator = font_families.find(family);
+	if (iterator != font_families.end())
+		font_family = (FontFamily*)(*iterator).second;
+	else
+	{
+		font_family = new FontFamily(family);
+		font_families[family] = font_family;
+	}
+
+	return font_family->AddFace((FT_Face) face, style, weight, release_stream);
+}
+
+// Loads a FreeType face.
+void* FontProvider::LoadFace(const String& file_name)
+{
+	FileInterface* file_interface = GetFileInterface();
+	FileHandle handle = file_interface->Open(file_name);
+
+	if (!handle)
+	{
+		return NULL;
+	}
+
+	size_t length = file_interface->Length(handle);
+
+	FT_Byte* buffer = new FT_Byte[length];
+	file_interface->Read(buffer, length, handle);
+	file_interface->Close(handle);
+
+	return LoadFace(buffer, (int)length, file_name, true);
+}
+
+// Loads a FreeType face from memory.
+void* FontProvider::LoadFace(const byte* data, int data_length, const String& source, bool local_data)
+{
+	FT_Face face = NULL;
+	int error = FT_New_Memory_Face(ft_library, (const FT_Byte*) data, data_length, 0, &face);
+	if (error != 0)
+	{
+		Log::Message(Log::LT_ERROR, "FreeType error %d while loading face from %s.", error, source.CString());
+		if (local_data)
+			delete[] data;
+
+		return NULL;
+	}
+
+	// Initialise the character mapping on the face.
+	if (face->charmap == NULL)
+	{
+		FT_Select_Charmap(face, FT_ENCODING_APPLE_ROMAN);
+		if (face->charmap == NULL)
+		{
+			Log::Message(Log::LT_ERROR, "Font face (from %s) does not contain a Unicode or Apple Roman character map.", source.CString());
+			FT_Done_Face(face);
+			if (local_data)
+				delete[] data;
+
+			return NULL;
+		}
+	}
+
+	return face;
+}
+
+}
+}
+}

+ 45 - 5
Source/Core/LayoutEngine.cpp

@@ -522,17 +522,33 @@ void LayoutEngine::BuildBoxWidth(Box& box, Element* element, float containing_bl
 		}
 		}
 	}
 	}
 
 
-	// If the width is set to auto, then any margins also set to auto are resolved to 0 and the width is set to the
-	// whatever if left of the containing block.
+	// If the width is set to auto, we need to calculate the width
 	if (width_auto)
 	if (width_auto)
 	{
 	{
+		float left = 0.0f, right = 0.0f;
+		// If we are dealing with an absolutely positioned element we need to
+		// consider if the left and right properties are set, since the width can be affected.
+		if (element->GetPosition() == POSITION_ABSOLUTE || 
+			element->GetPosition() == POSITION_FIXED)
+		{
+			Property const *left_property, *right_property;
+			element->GetOffsetProperties( NULL, NULL, &left_property, &right_property );
+			if (left_property->unit != Property::KEYWORD) 
+				left = element->ResolveProperty(left_property, containing_block_width );
+			if (right_property->unit != Property::KEYWORD) 
+				right = element->ResolveProperty(right_property, containing_block_width );
+		}
+
+		// We resolve any auto margins to 0 and the width is set to whatever is left of the containing block.
 		if (margins_auto[0])
 		if (margins_auto[0])
 			box.SetEdge(Box::MARGIN, Box::LEFT, 0);
 			box.SetEdge(Box::MARGIN, Box::LEFT, 0);
 		if (margins_auto[1])
 		if (margins_auto[1])
 			box.SetEdge(Box::MARGIN, Box::RIGHT, 0);
 			box.SetEdge(Box::MARGIN, Box::RIGHT, 0);
 
 
-		content_area.x = containing_block_width - (box.GetCumulativeEdge(Box::CONTENT, Box::LEFT) +
-												   box.GetCumulativeEdge(Box::CONTENT, Box::RIGHT));
+		content_area.x = containing_block_width - (left +
+		                                           box.GetCumulativeEdge(Box::CONTENT, Box::LEFT) +
+		                                           box.GetCumulativeEdge(Box::CONTENT, Box::RIGHT) +
+		                                           right);
 		content_area.x = Math::Max(0.0f, content_area.x);
 		content_area.x = Math::Max(0.0f, content_area.x);
 	}
 	}
 	// Otherwise, the margins that are set to auto will pick up the remaining width of the containing block.
 	// Otherwise, the margins that are set to auto will pick up the remaining width of the containing block.
@@ -622,15 +638,39 @@ void LayoutEngine::BuildBoxHeight(Box& box, Element* element, float containing_b
 		}
 		}
 	}
 	}
 
 
-	// If the height is set to auto, then any margins also set to auto are resolved to 0 and the height is set to -1.
+	// If the height is set to auto, we need to calculate the height
 	if (height_auto)
 	if (height_auto)
 	{
 	{
+		// We resolve any auto margins to 0
 		if (margins_auto[0])
 		if (margins_auto[0])
 			box.SetEdge(Box::MARGIN, Box::TOP, 0);
 			box.SetEdge(Box::MARGIN, Box::TOP, 0);
 		if (margins_auto[1])
 		if (margins_auto[1])
 			box.SetEdge(Box::MARGIN, Box::BOTTOM, 0);
 			box.SetEdge(Box::MARGIN, Box::BOTTOM, 0);
 
 
+		// If the height is set to auto for a box in normal flow, the height is set to -1.
 		content_area.y = -1;
 		content_area.y = -1;
+
+		// But if we are dealing with an absolutely positioned element we need to
+		// consider if the top and bottom properties are set, since the height can be affected.
+		if (element->GetPosition() == POSITION_ABSOLUTE || 
+			element->GetPosition() == POSITION_FIXED)
+		{
+			float top = 0.0f, bottom = 0.0f;
+			Property const *top_property, *bottom_property;
+			element->GetOffsetProperties( &top_property, &bottom_property, NULL, NULL );
+			if (top_property->unit != Property::KEYWORD && bottom_property->unit != Property::KEYWORD ) 
+			{
+				top = element->ResolveProperty(top_property, containing_block_height );
+				bottom = element->ResolveProperty(bottom_property, containing_block_height );
+
+				// The height gets resolved to whatever is left of the containing block
+				content_area.y = containing_block_height - (top +
+				                                            box.GetCumulativeEdge(Box::CONTENT, Box::TOP) +
+				                                            box.GetCumulativeEdge(Box::CONTENT, Box::BOTTOM) +
+				                                            bottom);
+				content_area.y = Math::Max(0.0f, content_area.y);
+			}
+		}
 	}
 	}
 	// Otherwise, the margins that are set to auto will pick up the remaining width of the containing block.
 	// Otherwise, the margins that are set to auto will pick up the remaining width of the containing block.
 	else if (num_auto_margins > 0)
 	else if (num_auto_margins > 0)

+ 8 - 8
Source/Core/Lua/Colourb.cpp

@@ -51,10 +51,10 @@ template<> void ExtraInit<Colourb>(lua_State* L, int metatable_index)
 }
 }
 int Colourbnew(lua_State* L)
 int Colourbnew(lua_State* L)
 {
 {
-    byte red = (byte)luaL_checkint(L,1);
-    byte green = (byte)luaL_checkint(L,2);
-    byte blue = (byte)luaL_checkint(L,3);
-    byte alpha = (byte)luaL_checkint(L,4);
+    byte red = (byte)luaL_checkinteger(L,1);
+    byte green = (byte)luaL_checkinteger(L,2);
+    byte blue = (byte)luaL_checkinteger(L,3);
+    byte alpha = (byte)luaL_checkinteger(L,4);
 
 
     Colourb* col = new Colourb(red,green,blue,alpha);
     Colourb* col = new Colourb(red,green,blue,alpha);
 
 
@@ -196,12 +196,12 @@ int ColourbSetAttrrgba(lua_State* L)
             if(top > 2)
             if(top > 2)
             {
             {
                 if(top > 3)
                 if(top > 3)
-                    obj->alpha = luaL_checkint(L,4);
-                obj->blue = luaL_checkint(L,3);
+                    obj->alpha = luaL_checkinteger(L,4);
+                obj->blue = luaL_checkinteger(L,3);
             }
             }
-            obj->green = luaL_checkint(L,2);
+            obj->green = luaL_checkinteger(L,2);
         }
         }
-        obj->red = luaL_checkint(L,1);
+        obj->red = luaL_checkinteger(L,1);
     }
     }
     return 0;
     return 0;
 }
 }

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

@@ -54,7 +54,7 @@ int ContextDocumentsProxy__index(lua_State* L)
         if(type == LUA_TSTRING)
         if(type == LUA_TSTRING)
             ret = proxy->owner->GetDocument(luaL_checkstring(L,2));
             ret = proxy->owner->GetDocument(luaL_checkstring(L,2));
         else
         else
-            ret = proxy->owner->GetDocument(luaL_checkint(L,2));
+            ret = proxy->owner->GetDocument(luaL_checkinteger(L,2));
         LuaType<Document>::push(L,ret,false);
         LuaType<Document>::push(L,ret,false);
         return 1;
         return 1;
     }
     }

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

@@ -495,7 +495,7 @@ int ElementGetAttrtag_name(lua_State* L)
     Element* ele = LuaType<Element>::check(L,1);
     Element* ele = LuaType<Element>::check(L,1);
     LUACHECKOBJ(ele);
     LUACHECKOBJ(ele);
     lua_pushstring(L,ele->GetTagName().CString());
     lua_pushstring(L,ele->GetTagName().CString());
-    return 0;
+    return 1;
 }
 }
 
 
 
 

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

@@ -51,7 +51,7 @@ int ElementChildNodesProxy__index(lua_State* L)
     {
     {
         ElementChildNodesProxy* obj = LuaType<ElementChildNodesProxy>::check(L,1);
         ElementChildNodesProxy* obj = LuaType<ElementChildNodesProxy>::check(L,1);
         LUACHECKOBJ(obj);
         LUACHECKOBJ(obj);
-        int key = luaL_checkint(L,2);
+        int key = luaL_checkinteger(L,2);
         Element* child = obj->owner->GetChild(key);
         Element* child = obj->owner->GetChild(key);
         LuaType<Element>::push(L,child,false);
         LuaType<Element>::push(L,child,false);
         return 1;
         return 1;

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

@@ -72,7 +72,7 @@ int rocket_pairs(lua_State* L)
 
 
 //copy + pasted from Lua's lbaselib.c
 //copy + pasted from Lua's lbaselib.c
 int ipairsaux (lua_State *L) {
 int ipairsaux (lua_State *L) {
-    int i = luaL_checkint(L, 2);
+    int i = luaL_checkinteger(L, 2);
     luaL_checktype(L, 1, LUA_TTABLE);
     luaL_checktype(L, 1, LUA_TTABLE);
     i++;  /* next value */
     i++;  /* next value */
     lua_pushinteger(L, i);
     lua_pushinteger(L, i);

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

@@ -60,7 +60,7 @@ int RocketContextsProxy__index(lua_State* L)
         }
         }
         else
         else
         {
         {
-            int key = luaL_checkint(L,2);
+            int key = luaL_checkinteger(L,2);
             LuaType<Context>::push(L,GetContext(key));
             LuaType<Context>::push(L,GetContext(key));
         }
         }
         return 1;
         return 1;

+ 6 - 6
Source/Core/Lua/Vector2i.cpp

@@ -58,8 +58,8 @@ template<> void ExtraInit<Vector2i>(lua_State* L, int metatable_index)
 
 
 int Vector2inew(lua_State* L)
 int Vector2inew(lua_State* L)
 {
 {
-    int x = luaL_checkint(L,1);
-    int y = luaL_checkint(L,2);
+    int x = luaL_checkinteger(L,1);
+    int y = luaL_checkinteger(L,2);
 
 
     Vector2i* vect = new Vector2i(x,y);
     Vector2i* vect = new Vector2i(x,y);
 
 
@@ -71,7 +71,7 @@ int Vector2i__mul(lua_State* L)
 {
 {
     Vector2i* lhs = LuaType<Vector2i>::check(L,1);
     Vector2i* lhs = LuaType<Vector2i>::check(L,1);
     LUACHECKOBJ(lhs);
     LUACHECKOBJ(lhs);
-    int rhs = luaL_checkint(L,2);
+    int rhs = luaL_checkinteger(L,2);
 
 
     Vector2i* res = new Vector2i(0,0);
     Vector2i* res = new Vector2i(0,0);
     (*res) = (*lhs) * rhs;
     (*res) = (*lhs) * rhs;
@@ -84,7 +84,7 @@ int Vector2i__div(lua_State* L)
 {
 {
     Vector2i* lhs = LuaType<Vector2i>::check(L,1);
     Vector2i* lhs = LuaType<Vector2i>::check(L,1);
     LUACHECKOBJ(lhs);
     LUACHECKOBJ(lhs);
-    int rhs = luaL_checkint(L,2);
+    int rhs = luaL_checkinteger(L,2);
 
 
     Vector2i* res = new Vector2i(0,0);
     Vector2i* res = new Vector2i(0,0);
     (*res) = (*lhs) / rhs;
     (*res) = (*lhs) / rhs;
@@ -163,7 +163,7 @@ int Vector2iSetAttrx(lua_State*L)
 {
 {
     Vector2i* self = LuaType<Vector2i>::check(L,1);
     Vector2i* self = LuaType<Vector2i>::check(L,1);
     LUACHECKOBJ(self);
     LUACHECKOBJ(self);
-    int value = luaL_checkint(L,2);
+    int value = luaL_checkinteger(L,2);
 
 
     self->x = value;
     self->x = value;
     return 0;
     return 0;
@@ -173,7 +173,7 @@ int Vector2iSetAttry(lua_State*L)
 {
 {
     Vector2i* self = LuaType<Vector2i>::check(L,1);
     Vector2i* self = LuaType<Vector2i>::check(L,1);
     LUACHECKOBJ(self);
     LUACHECKOBJ(self);
-    int value = luaL_checkint(L,2);
+    int value = luaL_checkinteger(L,2);
 
 
     self->y = value;
     self->y = value;
     return 0;
     return 0;

+ 1 - 0
Source/Core/StringCache.cpp

@@ -92,6 +92,7 @@ const String CURSOR = "cursor";
 const String DRAG = "drag";
 const String DRAG = "drag";
 const String TAB_INDEX = "tab-index";
 const String TAB_INDEX = "tab-index";
 const String SCROLLBAR_MARGIN = "scrollbar-margin";
 const String SCROLLBAR_MARGIN = "scrollbar-margin";
+const String SCROLL_DEFAULT_STEP_SIZE = "scroll-default-step-size";
 
 
 const String MOUSEDOWN = "mousedown";
 const String MOUSEDOWN = "mousedown";
 const String MOUSESCROLL = "mousescroll";
 const String MOUSESCROLL = "mousescroll";

+ 1 - 0
Source/Core/StringCache.h

@@ -95,6 +95,7 @@ extern const String CURSOR;
 extern const String DRAG;
 extern const String DRAG;
 extern const String TAB_INDEX;
 extern const String TAB_INDEX;
 extern const String SCROLLBAR_MARGIN;
 extern const String SCROLLBAR_MARGIN;
+extern const String SCROLL_DEFAULT_STEP_SIZE;
 
 
 extern const String MOUSEDOWN;
 extern const String MOUSEDOWN;
 extern const String MOUSESCROLL;
 extern const String MOUSESCROLL;

+ 4 - 1
Source/Core/TextureLayoutTexture.cpp

@@ -65,7 +65,10 @@ int TextureLayoutTexture::Generate(TextureLayout& layout, int maximum_dimensions
 
 
 		if (!rectangle.IsPlaced())
 		if (!rectangle.IsPlaced())
 		{
 		{
-			square_pixels += (rectangle.GetDimensions().x + 1) * (rectangle.GetDimensions().y + 1);
+			int x = rectangle.GetDimensions().x + 1;
+			int y = rectangle.GetDimensions().y + 1;
+
+			square_pixels += x*y;
 			++unplaced_rectangles;
 			++unplaced_rectangles;
 		}
 		}
 	}
 	}

+ 2 - 2
Source/Debugger/Plugin.cpp

@@ -286,8 +286,8 @@ Plugin* Plugin::GetInstance()
 
 
 bool Plugin::LoadFont()
 bool Plugin::LoadFont()
 {
 {
-	return (Core::FontDatabase::LoadFontFace(lacuna_regular, sizeof(lacuna_regular) / sizeof(unsigned char), "Lacuna", Core::Font::STYLE_NORMAL, Core::Font::WEIGHT_NORMAL) &&
-			Core::FontDatabase::LoadFontFace(lacuna_italic, sizeof(lacuna_italic) / sizeof(unsigned char), "Lacuna", Core::Font::STYLE_ITALIC, Core::Font::WEIGHT_NORMAL));
+	return (Core::FontDatabase::LoadFontFace(Core::FontDatabase::FreeType, lacuna_regular, sizeof(lacuna_regular) / sizeof(unsigned char), "Lacuna", Core::Font::STYLE_NORMAL, Core::Font::WEIGHT_NORMAL) &&
+			Core::FontDatabase::LoadFontFace(Core::FontDatabase::FreeType, lacuna_italic, sizeof(lacuna_italic) / sizeof(unsigned char), "Lacuna", Core::Font::STYLE_ITALIC, Core::Font::WEIGHT_NORMAL));
 }
 }
 
 
 bool Plugin::LoadMenuElement()
 bool Plugin::LoadMenuElement()

+ 2 - 2
how_to_build_for_mingw.txt

@@ -10,8 +10,8 @@ Go into the Build folder and run cmake. However, notice:
 ** REPLACE C:\MinGW\bin\mingw32-make.exe with the path to your MinGW make.exe file.
 ** REPLACE C:\MinGW\bin\mingw32-make.exe with the path to your MinGW make.exe file.
 ** You have to have the C:\MinGW\bin in the path (or cmake will complain for missing libgmp-10.dll, etc).
 ** You have to have the C:\MinGW\bin in the path (or cmake will complain for missing libgmp-10.dll, etc).
 ** You must not have msys/bin in the path, it doesn't work with cmake
 ** You must not have msys/bin in the path, it doesn't work with cmake
-** Use -DSTATIC_LIB if static libs are wanted. However, you will also need -DSTATIC_LIB to your own application when including Rocket files.
-** Notice that the generator "MinGW Makefiles" match the mingw32-make.exe, while the generator "msys Makefiles" match the msys/bin/make.exe. The first combination is used for 
+** Use -DROCKET_STATIC_LIB if static libs are wanted. However, you will also need -DROCKET_STATIC_LIB to your own application when including Rocket files.
+** Notice that the generator "MinGW Makefiles" match the mingw32-make.exe, while the generator "msys Makefiles" match the msys/bin/make.exe. The first combination is used for
 
 
 compiling from the DOS prompt, and the second one for compiling from a MinGW shell.
 compiling from the DOS prompt, and the second one for compiling from a MinGW shell.