Use ICU to support linebreaks in languages that unibreak cannot support.
This patch generates libdali2-icu-plugin.so.
TextAbstraction::ICU dynamically loads icu-plugin.so if needed.
Change-Id: I74fb0b5c0f8b5bcd6a7889213e71c3528d4a0124
Signed-off-by: Bowon Ryu <bowon.ryu@samsung.com>
if test "x$with_tizen_65_or_greater" = "xyes"; then
AC_CONFIG_SUBDIRS(camera-player)
+ AC_CONFIG_SUBDIRS(icu)
AC_CONFIG_SUBDIRS(rive-animation-view)
fi
--- /dev/null
+#
+# Copyright (c) 2025 Samsung Electronics Co., Ltd.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Build the Dali feedback plugin
+
+extension_src_dir = ../../../dali-extension
+
+include ../../../dali-extension/icu/file.list
+
+lib_LTLIBRARIES =
+
+lib_LTLIBRARIES += libdali2-icu-plugin.la
+
+libdali2_icu_plugin_la_includes =
+
+libdali2_icu_plugin_la_SOURCES = \
+ $(icu_plugin_src_files)
+
+libdali2_icu_plugin_la_DEPENDENCIES =
+
+libdali2_icu_plugin_la_CXXFLAGS = \
+ $(DLOG_CFLAGS) \
+ $(DALI_CFLAGS) \
+ $(ICU_CFLAGS) \
+ -Werror -Wall
+
+libdali2_icu_plugin_la_CXXFLAGS+= \
+ -I../../../dali-extension/icu
+
+libdali2_icu_plugin_la_LIBADD = \
+ $(DLOG_LIBS) \
+ $(DALI_LIBS) \
+ $(ICU_LIBS)
+
+libdali2_icu_plugin_la_LDFLAGS = \
+ -rdynamic
+
--- /dev/null
+4_define([dali_version],[0.1.0])
+AC_INIT([dali], [dali_version])
+AM_INIT_AUTOMAKE([-Wall foreign])
+
+AC_CONFIG_MACRO_DIRS([m4 ../m4])
+
+AC_PROG_CXX
+AC_PROG_LIBTOOL
+
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+
+AX_CXX_COMPILE_STDCXX([17], [noext], [mandatory])
+
+LT_INIT
+
+DALI_EXTENSION_VERSION=dali_version
+AC_SUBST(DALI_EXTENSION_VERSION)
+
+if test "x$enable_debug" = "xyes"; then
+ DALI_CFLAGS="$DALI_CFLAGS -DDEBUG_ENABLED"
+fi
+
+PKG_CHECK_MODULES([DALI], [dali2-core dali2-adaptor dali2-toolkit])
+PKG_CHECK_MODULES([ICU], [icu-i18n icu-uc])
+
+devincludepath=${includedir}
+AC_SUBST(devincludepath)
+AC_SUBST(DALI_CFLAGS)
+
+AC_CONFIG_FILES([
+Makefile
+])
+
+AC_OUTPUT
GET_FILENAME_COMPONENT(ROOT_SRC_DIR ${ROOT_SRC_DIR} ABSOLUTE)
ADD_SUBDIRECTORY(vector-animation-renderer)
+ADD_SUBDIRECTORY(icu)
--- /dev/null
+SET(name "dali2-icu-plugin")
+
+SET(CMAKE_C_STANDARD 99)
+SET(CMAKE_CXX_STANDARD 17)
+PROJECT(${name})
+SET(PKG_NAME ${name})
+
+SET(GCC_COMPILER_VERSION_REQUIRED "6")
+IF(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ IF(CMAKE_CXX_COMPILER_VERSION VERSION_LESS GCC_COMPILER_VERSION_REQUIRED)
+ MESSAGE(FATAL_ERROR "The GCC required compiler version is " ${GCC_COMPILER_VERSION_REQUIRED})
+ ENDIF()
+ENDIF()
+
+IF( ENABLE_PKG_CONFIGURE )
+ FIND_PACKAGE( PkgConfig REQUIRED )
+ PKG_CHECK_MODULES(DALICORE REQUIRED dali2-core)
+ PKG_CHECK_MODULES(DALIADAPTOR REQUIRED dali2-adaptor)
+ PKG_CHECK_MODULES(DALITOOLKIT REQUIRED dali2-toolkit)
+ PKG_CHECK_MODULES(ICU REQUIRED icu-i18n)
+ PKG_CHECK_MODULES(ICU REQUIRED icu-uc)
+ENDIF()
+
+# Deployment folder should come from spec file or command line:
+SET( PREFIX ${CMAKE_INSTALL_PREFIX})
+SET( EXEC_PREFIX ${CMAKE_INSTALL_PREFIX})
+
+# Set up the include dir
+SET( INCLUDE_DIR $ENV{includedir} )
+IF( NOT INCLUDE_DIR )
+ SET( INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR} )
+ENDIF()
+IF( NOT INCLUDE_DIR )
+ SET( INCLUDE_DIR ${PREFIX}/include )
+ENDIF()
+
+# Set up the lib dir
+SET( LIB_DIR $ENV{libdir} )
+IF( NOT LIB_DIR )
+ SET( LIB_DIR ${CMAKE_INSTALL_LIBDIR} )
+ENDIF()
+IF( NOT LIB_DIR )
+ SET( LIB_DIR ${PREFIX}/lib )
+ENDIF()
+
+# Set up the bin dir
+SET( BIN_DIR $ENV{bindir} )
+IF( NOT BIN_DIR )
+ SET( BIN_DIR ${CMAKE_INSTALL_BINDIR} )
+ENDIF()
+IF( NOT BIN_DIR )
+ SET( BIN_DIR ${PREFIX}/bin )
+ENDIF()
+
+IF( ENABLE_DEBUG )
+ MESSAGE( STATUS "CMAKE_BUILD_TYPE: " Debug )
+ ADD_DEFINITIONS( "-DDEBUG_ENABLED" )
+ SET( ENABLE_EXPORTALL ON )
+ELSE()
+ MESSAGE( STATUS "CMAKE_BUILD_TYPE: " Release )
+ENDIF()
+
+IF( ENABLE_TRACE )
+ ADD_DEFINITIONS("-DTRACE_ENABLED")
+ENDIF()
+
+# Hijack the information of tizen version here
+ADD_DEFINITIONS("-DOVER_TIZEN_VERSION_9")
+
+INCLUDE(CheckCXXCompilerFlag)
+
+ADD_COMPILE_OPTIONS( -Werror -Wall -Wextra -Wno-unused-parameter -Wfloat-equal )
+CHECK_CXX_COMPILER_FLAG(-Wno-class-memaccess HAVE_NO_CLASS_MEMACCESS)
+IF (HAVE_NO_CLASS_MEMACCESS)
+ ADD_COMPILE_OPTIONS( -Wno-class-memaccess )
+ENDIF()
+
+CHECK_CXX_COMPILER_FLAG(-Wno-cast-function-type HAVE_NO_CAST_FUNCTION_TYPE)
+IF (HAVE_NO_CAST_FUNCTION_TYPE)
+ ADD_COMPILE_OPTIONS( -Wno-cast-function-type )
+ENDIF()
+
+IF( NOT ${ENABLE_EXPORTALL} )
+ ADD_COMPILE_OPTIONS( "-fvisibility=hidden" )
+ENDIF()
+
+SET(SOURCE_DIR "${ROOT_SRC_DIR}/dali-extension/icu")
+
+SET(SOURCES "")
+
+INCLUDE_DIRECTORIES(
+ ${ROOT_SRC_DIR}
+ ${DALICORE_INCLUDE_DIRS}
+ ${DALIADAPTOR_INCLUDE_DIRS}
+ ${INCLUDE_DIR}
+ ${SOURCE_DIR}
+)
+
+INCLUDE( ${ROOT_SRC_DIR}/dali-extension/icu/file-ubuntu.list )
+
+SET(LIBTYPE SHARED)
+IF(DEFINED STATIC)
+ SET(LIBTYPE STATIC)
+ENDIF()
+
+ADD_LIBRARY( ${name} ${LIBTYPE} ${SOURCES} )
+
+SET(OPTIONAL_LIBS ${OPTIONAL_LIBS} -lpthread)
+
+TARGET_LINK_LIBRARIES( ${name}
+ ${OPTIONAL_LIBS}
+ ${DALICORE_LDFLAGS}
+ ${DALIADAPTOR_LDFLAGS}
+ ${ICU_LDFLAGS}
+)
+
+IF( INSTALL_CMAKE_MODULES )
+ IF( ENABLE_DEBUG )
+ SET( BIN_DIR "${BIN_DIR}/debug" )
+ SET( LIB_DIR "${LIB_DIR}/debug" )
+ ENDIF()
+
+ # Install the library files.
+ INSTALL( TARGETS ${name}
+ EXPORT ${name}-targets
+ LIBRARY DESTINATION ${LIB_DIR}
+ ARCHIVE DESTINATION ${LIB_DIR}
+ RUNTIME DESTINATION ${BIN_DIR}
+ )
+
+ # Install the cmake modules.
+ INSTALL(
+ EXPORT ${name}-targets
+ NAMESPACE ${name}::
+ FILE ${name}-targets.cmake
+ DESTINATION share/${name}
+ )
+
+ FILE( WRITE ${CMAKE_CURRENT_BINARY_DIR}/${name}-config.cmake "
+ include(CMakeFindDependencyMacro)
+ include(\${CMAKE_CURRENT_LIST_DIR}/${name}-targets.cmake)
+ ")
+ INSTALL( FILES ${CMAKE_CURRENT_BINARY_DIR}/${name}-config.cmake DESTINATION share/${name} )
+
+ELSE()
+ # Install the library so file and symlinks.
+ INSTALL( TARGETS ${name} DESTINATION ${LIB_DIR} )
+ENDIF()
+
+# Configuration Messages
+MESSAGE( STATUS "Configuration:\n" )
+MESSAGE( STATUS "Prefix: " ${PREFIX} )
+MESSAGE( STATUS "Lib Dir: " ${LIB_DIR} )
+MESSAGE( STATUS "Bin Dir: " ${BIN_DIR} )
+MESSAGE( STATUS "Include Dir: " ${INCLUDE_DIR} )
+MESSAGE( STATUS "Debug build: " ${ENABLE_DEBUG} )
+MESSAGE( STATUS "Export all symbols: " ${ENABLE_EXPORTALL} )
+MESSAGE( STATUS "Trace: " ${ENABLE_TRACE} )
+MESSAGE( STATUS "Use pkg configure: " ${ENABLE_PKG_CONFIGURE} )
+MESSAGE( STATUS "CXXFLAGS: " ${CMAKE_CXX_FLAGS} )
+MESSAGE( STATUS "LDFLAGS: " ${CMAKE_SHARED_LINKER_FLAGS_INIT}${CMAKE_SHARED_LINKER_FLAGS} )
--- /dev/null
+SET( root_dir ${ROOT_SRC_DIR}/dali-extension/icu )
+
+SET( SOURCES ${SOURCES}
+ ${root_dir}/icu.cpp
+)
--- /dev/null
+icu_plugin_src_files = \
+ $(extension_src_dir)/icu/icu.cpp
--- /dev/null
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <icu.h>
+
+// EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+
+#include <unicode/brkiter.h>
+#include <unicode/unistr.h>
+#include <unicode/ustream.h>
+
+// INTERNAL INCLUDES
+
+// The plugin factories
+extern "C" DALI_EXPORT_API Dali::TextAbstraction::ICUPlugin *CreateICUPlugin()
+{
+ return new Dali::Plugin::ICU();
+}
+
+extern "C" DALI_EXPORT_API void DestroyICUPlugin(Dali::TextAbstraction::ICUPlugin *plugin)
+{
+ if (plugin != nullptr)
+ {
+ delete plugin;
+ }
+}
+
+namespace Dali
+{
+namespace Plugin
+{
+namespace
+{
+} // unnamed namespace
+
+ICU::ICU()
+{
+
+}
+
+ICU::~ICU()
+{
+
+}
+
+void ICU::UpdateLineBreakInfoByLocale(const std::string& text,
+ TextAbstraction::Length numberOfCharacters,
+ const char* locale,
+ TextAbstraction::LineBreakInfo* breakInfo)
+{
+ icu::UnicodeString unicodeText = icu::UnicodeString::fromUTF8(text);
+ if(static_cast<uint32_t>(unicodeText.length()) != numberOfCharacters)
+ {
+ DALI_LOG_ERROR("UnicodeString len : %lu, numberOfCharacters : %lu\n", static_cast<uint32_t>(unicodeText.length()), numberOfCharacters);
+ return;
+ }
+
+ icu::Locale icuLocale(locale);
+
+ UErrorCode status = U_ZERO_ERROR;
+ std::unique_ptr<icu::BreakIterator> lineIterator(icu::BreakIterator::createLineInstance(icuLocale, status));
+
+ if(U_FAILURE(status))
+ {
+ DALI_LOG_ERROR("Failed to create BreakIterator: %s\n", u_errorName(status));
+ return;
+ }
+
+ lineIterator->setText(unicodeText);
+
+ for(int32_t pos = lineIterator->first(); pos != icu::BreakIterator::DONE; pos = lineIterator->next())
+ {
+ if(pos != 0 && breakInfo[pos - 1] != TextAbstraction::LINE_MUST_BREAK)
+ {
+ breakInfo[pos - 1] = TextAbstraction::LINE_ALLOW_BREAK;
+ }
+ }
+}
+
+} // namespace Plugin
+} // namespace Dali
--- /dev/null
+#ifndef DALI_ICU_PLUGIN_H
+#define DALI_ICU_PLUGIN_H
+
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/text-abstraction/icu-plugin.h>
+
+namespace Dali
+{
+namespace Plugin
+{
+
+/**
+ * @brief Implementation of the ICU class which has Tizen platform dependency.
+ */
+class ICU : public Dali::TextAbstraction::ICUPlugin
+{
+public:
+
+ /**
+ * @brief Constructor.
+ */
+ ICU();
+
+ /**
+ * @brief Destructor.
+ */
+ virtual ~ICU();
+
+ /**
+ * @copydoc Dali::TextAbstraction::ICUPlugin::UpdateLineBreakInfoByLocale()
+ */
+ void UpdateLineBreakInfoByLocale(const std::string& text,
+ TextAbstraction::Length numberOfCharacters,
+ const char* locale,
+ TextAbstraction::LineBreakInfo* breakInfo) override;
+};
+
+} // namespace Plugin
+} // namespace Dali
+
+#endif // DALI_ICU_PLUGIN_H
%description rive-animation-view-devel
Header & package configuration of rive-animation-view
+##############################
+# Dali ICU Plugin
+##############################
+
+%package icu-plugin
+Summary: Plugin to use an International Components for Unicode for Dali
+Group: System/Libraries
+BuildRequires: pkgconfig(icu-i18n)
+BuildRequires: pkgconfig(icu-uc)
+
+%description icu-plugin
+ICU plugin to use an International Components for Unicode for Dali
+
##############################
# Preparation
##############################
/sbin/ldconfig
exit 0
+%post icu-plugin
+/sbin/ldconfig
+exit 0
+
%if 0%{?tizen_55_or_greater} && 0%{?enable_web_engine_plugin} == 1
%post web-engine-chromium-plugin
pushd %{_libdir}
/sbin/ldconfig
exit 0
+%postun icu-plugin
+/sbin/ldconfig
+exit 0
+
%if 0%{?tizen_55_or_greater} && 0%{?enable_web_engine_plugin} == 1
%postun web-engine-chromium-plugin
/sbin/ldconfig
%license LICENSE
%endif
+%if 0%{?tizen_65_or_greater}
+%files icu-plugin
+%manifest dali-extension.manifest
+%defattr(-,root,root,-)
+%{_libdir}/libdali2-icu-plugin.so*
+%license LICENSE
+%endif
+
%if 0%{?tizen_55_or_greater} && 0%{?enable_web_engine_plugin} == 1
%files web-engine-chromium-plugin
%manifest dali-extension.manifest