Skip to content

Commit

Permalink
Merge pull request #22 from brisklib/i18n
Browse files Browse the repository at this point in the history
Ability to select i18n implementation
  • Loading branch information
dancazarin authored Jan 15, 2025
2 parents ab71003 + 5826884 commit 0bdeaa4
Show file tree
Hide file tree
Showing 13 changed files with 393 additions and 246 deletions.
22 changes: 15 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ project(
VERSION ${BRISK_VERSION}
LANGUAGES CXX C)


get_directory_property(BRISK_PARENT_DIR PARENT_DIRECTORY)
if (NOT BRISK_PARENT_DIR)
set(BRISK_STANDALONE TRUE)
endif()

if (DEBUG_CMAKE)
get_cmake_property(VARS VARIABLES)
list(SORT VARS)
Expand All @@ -54,7 +60,7 @@ else ()
set(ENABLE_WEBGPU OFF)
endif ()
option(BRISK_WEBGPU "Enable WebGPU" ${ENABLE_WEBGPU})
option(BRISK_ICU "Enable full Unicode support" ON)
option(BRISK_ICU "Link to ICU by default for full Unicode support" ON)
option(BRISK_GONOTO "Include GoNoto font" OFF)
option(BRISK_LOG_TO_STDERR "Write log output to stderr (Windows-specific)" OFF)

Expand Down Expand Up @@ -175,12 +181,13 @@ if (BRISK_TESTS)
${TESTS_GRAPHICS}
LIBRARIES
brisk-graphics
brisk-i18n-icu
${TESTS_GRAPHICS_LIBS}
DEFINITIONS
${TESTS_GRAPHICS_DEFS})
add_autotests(window SOURCES ${TESTS_WINDOW} LIBRARIES brisk-window)
add_autotests(gui SOURCES ${TESTS_GUI} LIBRARIES brisk-gui)
add_autotests(widgets SOURCES ${TESTS_WIDGETS} LIBRARIES brisk-widgets)
add_autotests(window SOURCES ${TESTS_WINDOW} LIBRARIES brisk-window brisk-i18n-icu)
add_autotests(gui SOURCES ${TESTS_GUI} LIBRARIES brisk-gui brisk-i18n-icu)
add_autotests(widgets SOURCES ${TESTS_WIDGETS} LIBRARIES brisk-widgets brisk-i18n-icu)

endif ()

Expand Down Expand Up @@ -226,6 +233,8 @@ install(
brisk-gui
brisk-widgets
brisk-executable
brisk-i18n
brisk-i18n-icu
${EXTRA_INSTALL_TARGETS}
EXPORT BriskTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}$<$<CONFIG:Debug>:${BRISK_DBG_SUFFIX}>
Expand Down Expand Up @@ -272,6 +281,5 @@ install(
RENAME README.md
DESTINATION .)

install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/DEP_HASH ${CMAKE_CURRENT_BINARY_DIR}/VCPKG_TARGET_TRIPLET
DESTINATION ${BRISK_INSTALL_CMAKEDIR})
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/DEP_HASH ${CMAKE_CURRENT_BINARY_DIR}/VCPKG_TARGET_TRIPLET
DESTINATION ${BRISK_INSTALL_CMAKEDIR})
9 changes: 0 additions & 9 deletions cmake/brisk.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,6 @@ set(BRISK_ROOT

include(${CMAKE_CURRENT_LIST_DIR}/init.cmake)

if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
set(BRISK_STANDALONE TRUE)
endif ()

file(STRINGS ${CMAKE_CURRENT_LIST_DIR}/../include/brisk/core/Version.hpp BRISK_VERSION
REGEX "#define BRISK_VERSION_(MINOR|MAJOR|PATCH)")
string(REGEX MATCHALL "[0-9]+" BRISK_VERSION_MATCH ${BRISK_VERSION})
Expand All @@ -43,10 +39,5 @@ string(REPLACE ";" "." BRISK_VERSION "${BRISK_VERSION_MATCH}")
message(STATUS "BRISK ${BRISK_VERSION}, ROOT = ${BRISK_ROOT}")

macro (brisk_setup)

if (NOT BRISK_STANDALONE)
execute_process()
endif ()

add_subdirectory(${BRISK_ROOT} brisk-bin)
endmacro ()
8 changes: 7 additions & 1 deletion cmake/config.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ add_library(brisk-gui ALIAS Brisk::GUI)
add_library(brisk-widgets ALIAS Brisk::Widgets)
add_library(brisk-network ALIAS Brisk::Network)
add_library(brisk-executable ALIAS Brisk::Executable)
add_library(brisk-i18n-icu ALIAS Brisk::I18n-ICU)

get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_BRISK_INCLUDE_DIR "${_DIR}/../../../include" ABSOLUTE)
Expand All @@ -24,7 +25,12 @@ include(CMakeFindDependencyMacro)

set(BRISK_BROTLI @BRISK_BROTLI@)
set(BRISK_WEBGPU @BRISK_WEBGPU@)
set(BRISK_ICU @BRISK_ICU@)

if (BRISK_ICU)
target_link_libraries(Brisk::Graphics INTERFACE Brisk::I18n-ICU)
else()
target_link_libraries(Brisk::Graphics INTERFACE Brisk::I18n)
endif ()

set(_DEP_PUBLIC INTERFACE)
set(_DEP_PRIVATE INTERFACE)
Expand Down
71 changes: 27 additions & 44 deletions include/brisk/graphics/Fonts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "Image.hpp"
#include <brisk/core/IO.hpp>
#include "internal/Sprites.hpp"
#include "I18n.hpp"

namespace Brisk {

Expand All @@ -21,37 +22,8 @@ class EFreeType : public ELogic {
using ELogic::ELogic;
};

enum class TextBreakMode {
Grapheme,
Word,
Line,
};

constexpr auto operator+(TextBreakMode value) noexcept {
return static_cast<std::underlying_type_t<decltype(value)>>(value);
}

std::vector<uint32_t> textBreakPositions(std::u32string_view text, TextBreakMode mode);

using GlyphID = uint32_t;

enum class TextDirection : uint8_t {
LTR,
RTL,
};

struct BidiText {
std::optional<TextDirection> direction; // nullopt means mixed
};

RC<BidiText> bidiText(std::u32string_view text, TextDirection defaultDirection);

template <>
inline constexpr std::initializer_list<NameValuePair<TextDirection>> defaultNames<TextDirection>{
{ "LTR", TextDirection::LTR },
{ "RTL", TextDirection::RTL },
};

enum class LayoutOptions : uint32_t {
Default = 0,
SingleLine = 1,
Expand Down Expand Up @@ -300,21 +272,6 @@ struct TextRun {
};
};

/**
* @brief Splits a string of text into multiple `TextRun` objects based on directionality.
*
* This function analyzes the given text and segments it into runs of uniform properties. It takes into
* account the specified default text direction and optionally applies visual order for bidirectional text.
*
* @param text The text to be split into text runs.
* @param defaultDirection The default text direction to use if no explicit directionality is detected.
* @param visualOrder If `true`, the resulting text runs will be reordered to match the visual order of the
* text.
* @return std::vector<TextRun> A vector of `TextRun` objects representing the segmented text.
*/
std::vector<TextRun> splitTextRuns(std::u32string_view text, TextDirection defaultDirection,
bool visualOrder);

/**
* @enum GlyphFlags
* @brief Flags used to define various properties of glyphs.
Expand Down Expand Up @@ -1099,6 +1056,32 @@ class FontManager final {

extern std::optional<FontManager> fonts;

inline std::vector<uint32_t> textBreakPositions(std::u32string_view text, TextBreakMode mode) {
std::vector<uint32_t> result(1, 0);
RC<Internal::TextBreakIterator> iter = Internal::textBreakIterator(text, mode);
while (auto p = iter->next()) {
result.push_back(*p);
}
return result;
}

namespace Internal {
/**
* @brief Splits a string of text into multiple `TextRun` objects based on directionality.
*
* This function analyzes the given text and segments it into runs of uniform properties. It takes into
* account the specified default text direction and optionally applies visual order for bidirectional text.
*
* @param text The text to be split into text runs.
* @param defaultDirection The default text direction to use if no explicit directionality is detected.
* @param visualOrder If `true`, the resulting text runs will be reordered to match the visual order of the
* text.
* @return std::vector<TextRun> A vector of `TextRun` objects representing the segmented text.
*/
std::vector<TextRun> splitTextRuns(std::u32string_view text, TextDirection defaultDirection,
bool visualOrder);
} // namespace Internal

/**
* @brief Indicates whether the ICU library is available for full Unicode support.
*
Expand Down
64 changes: 64 additions & 0 deletions include/brisk/graphics/I18n.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#pragma once

#include "brisk/core/BasicTypes.hpp"
#include "brisk/core/RC.hpp"
#include "brisk/core/Reflection.hpp"
#include <cstdint>
#include <vector>
#include <string_view>
#include <type_traits>

namespace Brisk {

enum class TextBreakMode {
Grapheme,
Word,
Line,
};

constexpr auto operator+(TextBreakMode value) noexcept {
return static_cast<std::underlying_type_t<decltype(value)>>(value);
}

enum class TextDirection : uint8_t {
LTR,
RTL,
};

template <>
inline constexpr std::initializer_list<NameValuePair<TextDirection>> defaultNames<TextDirection>{
{ "LTR", TextDirection::LTR },
{ "RTL", TextDirection::RTL },
};

namespace Internal {

class TextBreakIterator {
public:
virtual ~TextBreakIterator() = 0;
virtual std::optional<uint32_t> next() = 0;
};

RC<TextBreakIterator> textBreakIterator(std::u32string_view text, TextBreakMode mode);

class BidiTextIterator {
public:
virtual ~BidiTextIterator();
virtual bool isMixed() const = 0;

struct TextFragment {
Range<uint32_t> codepointRange;
uint32_t visualPosition;
uint8_t level;
TextDirection direction;
};

virtual std::optional<TextFragment> next() = 0;
};

RC<BidiTextIterator> bidiTextIterator(std::u32string_view text, TextDirection defaultDirection);

} // namespace Internal


} // namespace Brisk
2 changes: 1 addition & 1 deletion src/core/Deps.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ target_link_libraries(${_BRISK_CORE} ${_DEP_PRIVATE} msgpack-cxx)

# >utf8proc
find_package(unofficial-utf8proc CONFIG REQUIRED)
target_link_libraries(${_BRISK_CORE} ${_DEP_PRIVATE} utf8proc)
target_link_libraries(${_BRISK_CORE} ${_DEP_PUBLIC} utf8proc)
# /utf8proc

# >zlib
Expand Down
38 changes: 24 additions & 14 deletions src/graphics/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ add_library(
${PROJECT_SOURCE_DIR}/include/brisk/graphics/Fonts.hpp
${PROJECT_SOURCE_DIR}/include/brisk/graphics/Path.hpp
${PROJECT_SOURCE_DIR}/include/brisk/graphics/Offscreen.hpp
${PROJECT_SOURCE_DIR}/src/graphics/ICU.cpp
${PROJECT_SOURCE_DIR}/src/graphics/Gradients.cpp
${PROJECT_SOURCE_DIR}/src/graphics/SVG.cpp
${PROJECT_SOURCE_DIR}/src/graphics/ImageFormats_png.cpp
Expand Down Expand Up @@ -96,6 +95,30 @@ endif ()

target_compile_definitions(brisk-graphics PRIVATE V_NAMESPACE=Brisk)

add_library(brisk-i18n STATIC ${PROJECT_SOURCE_DIR}/src/graphics/I18n_fallback.cpp)
target_link_libraries(brisk-i18n PUBLIC brisk-core)
add_library(Brisk::I18n ALIAS brisk-i18n)
set_property(TARGET brisk-i18n PROPERTY EXPORT_NAME I18n)

set(ICU_DT icudt74l.dat)
file(SIZE "${PROJECT_SOURCE_DIR}/resources/icu/${ICU_DT}" ICUDT_SIZE)

add_library(brisk-i18n-icu STATIC ${PROJECT_SOURCE_DIR}/src/graphics/I18n.cpp)
add_library(Brisk::I18n-ICU ALIAS brisk-i18n-icu)
set_property(TARGET brisk-i18n-icu PROPERTY EXPORT_NAME I18n-ICU)
target_link_libraries(brisk-i18n-icu PUBLIC brisk-core)
target_compile_definitions(brisk-i18n-icu PRIVATE ICUDT_SIZE=${ICUDT_SIZE})
brisk_target_link_resource(
brisk-i18n-icu PRIVATE icudt
INPUT "${PROJECT_SOURCE_DIR}/resources/icu/${ICU_DT}"
BROTLI)

if (BRISK_ICU)
target_link_libraries(brisk-graphics INTERFACE $<BUILD_INTERFACE:brisk-i18n-icu>)
else()
target_link_libraries(brisk-graphics INTERFACE $<BUILD_INTERFACE:brisk-i18n>)
endif ()

if (BRISK_WEBGPU)
add_subdirectory(WebGPURenderer)
endif ()
Expand All @@ -117,19 +140,6 @@ if (BRISK_WEBGPU)
endif ()
endif ()

if (BRISK_ICU)
if (TARGET ICU::uc)
set(ICU_DT icudt74l.dat)
file(SIZE "${PROJECT_SOURCE_DIR}/resources/icu/${ICU_DT}" ICUDT_SIZE)
brisk_target_link_resource(
brisk-graphics PRIVATE icudt
INPUT "${PROJECT_SOURCE_DIR}/resources/icu/${ICU_DT}"
BROTLI)
set_source_files_properties(${PROJECT_SOURCE_DIR}/src/graphics/ICU.cpp PROPERTIES COMPILE_DEFINITIONS
ICUDT_SIZE=${ICUDT_SIZE})
endif ()
endif ()

set_target_properties(brisk-graphics PROPERTIES CXX_CLANG_TIDY "${CLANG_TIDY_ARGS}")

if (APPLE)
Expand Down
18 changes: 11 additions & 7 deletions src/graphics/Deps.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ if ("${_BRISK_GRAPHICS}" STREQUAL "")
set(_BRISK_GRAPHICS brisk-graphics)
endif ()

get_property(
_BRISK_I18N_ICU
TARGET brisk-i18n-icu
PROPERTY ALIASED_TARGET)
if ("${_BRISK_I18N_ICU}" STREQUAL "")
set(_BRISK_I18N_ICU brisk-i18n-icu)
endif ()

# >PNG
find_package(PNG REQUIRED)
target_link_libraries(${_BRISK_GRAPHICS} ${_DEP_PRIVATE} PNG::PNG)
Expand Down Expand Up @@ -39,16 +47,12 @@ target_link_libraries(${_BRISK_GRAPHICS} ${_DEP_PRIVATE} freetype)
# /freetype

# >icu
if (BRISK_ICU)
find_package(ICU COMPONENTS uc)
if (TARGET ICU::uc)
target_link_libraries(${_BRISK_GRAPHICS} ${_DEP_PRIVATE} ICU::uc)
endif ()
endif ()
find_package(ICU COMPONENTS uc REQUIRED)
target_link_libraries(${_BRISK_I18N_ICU} ${_DEP_PRIVATE} ICU::uc)
# /icu

if (BRISK_WEBGPU)
find_package(Dawn CONFIG)
find_package(Dawn CONFIG REQUIRED)
if (TARGET Brisk::brisk-renderer-webgpu)
target_link_libraries(Brisk::brisk-renderer-webgpu ${_DEP_PRIVATE} Dawn)
else ()
Expand Down
1 change: 0 additions & 1 deletion src/graphics/Fonts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,6 @@ static void toVisualOrder(std::vector<TextRun>& textRuns) {
}

// Split text into runs of the same direction
// Defined in ICU.cpp
std::vector<TextRun> splitTextRuns(std::u32string_view text, TextDirection defaultDirection);

std::vector<TextRun> splitTextRuns(std::u32string_view text, TextDirection defaultDirection,
Expand Down
Loading

0 comments on commit 0bdeaa4

Please sign in to comment.