Dali ICU class dynamically loads icu.so via ICUPLugin of dali-extension.
* ICUPlugin is an abstract interface, used by dali-adaptor to access icu plugin.
Change-Id: I1f2b9c702ee000a13e733cc5c232b7c66d256149
Signed-off-by: Bowon Ryu <bowon.ryu@samsung.com>
${adaptor_devel_api_dir}/text-abstraction/text-renderer.cpp
${adaptor_devel_api_dir}/text-abstraction/text-renderer-layout-helper.cpp
${adaptor_devel_api_dir}/text-abstraction/hyphenation.cpp
+ ${adaptor_devel_api_dir}/text-abstraction/icu.cpp
${adaptor_devel_api_dir}/text-abstraction/emoji-character-properties.cpp
${adaptor_devel_api_dir}/text-abstraction/emoji-helper.cpp
)
${adaptor_devel_api_dir}/text-abstraction/text-renderer.h
${adaptor_devel_api_dir}/text-abstraction/text-renderer-layout-helper.h
${adaptor_devel_api_dir}/text-abstraction/hyphenation.h
+ ${adaptor_devel_api_dir}/text-abstraction/icu.h
+ ${adaptor_devel_api_dir}/text-abstraction/icu-plugin.h
${adaptor_devel_api_dir}/text-abstraction/emoji-character-properties.h
${adaptor_devel_api_dir}/text-abstraction/emoji-helper.h
${adaptor_devel_api_dir}/text-abstraction/defined-characters.h
--- /dev/null
+#ifndef DALI_PLATFORM_TEXT_ABSTRACTION_ICU_PLUGIN_H
+#define DALI_PLATFORM_TEXT_ABSTRACTION_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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/devel-api/text-abstraction/text-abstraction-definitions.h>
+
+// EXTERNAL INCLUDES
+#include <string>
+
+namespace Dali
+{
+namespace TextAbstraction
+{
+
+/**
+ * @brief ICUPlugin is an abstract interface, used by dali-adaptor to access icu plugin.
+ * A concrete implementation must be created for each platform and provided as dynamic library.
+ */
+class ICUPlugin
+{
+public:
+ /**
+ * @brief Constructor.
+ */
+ ICUPlugin()
+ {
+ }
+
+ /**
+ * @brief Destructor.
+ */
+ virtual ~ICUPlugin()
+ {
+ }
+
+ /**
+ * @brief Update line break information by ICU.
+ * @remark Updates given line break information with ICU dictionary-based word wrap information that unibreak does not support.
+ * @param[in] text A string of UTF-8 characters.
+ * @param[in] numberOfCharacters The number of characters.
+ * @param[in] locale The locale code. (en, ko, en_US, ko_KR.utf8, etc. ICU accepts most formats of locale code), The usual expected form is language_locale (ko_KR).
+ * @param[out] breakInfo The unibreak line break information buffer.
+ */
+ virtual void UpdateLineBreakInfoByLocale(const std::string& text,
+ Length numberOfCharacters,
+ const char* locale,
+ LineBreakInfo* breakInfo) = 0;
+};
+
+} // namespace TextAbstraction
+
+} // namespace Dali
+
+#endif // DALI_PLATFORM_TEXT_ABSTRACTION_ICU_PLUGIN_H
--- /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 <dali/devel-api/text-abstraction/icu.h>
+
+// INTERNAL INCLUDES
+#include <dali/internal/text/text-abstraction/icu-impl.h>
+
+namespace Dali
+{
+namespace TextAbstraction
+{
+ICU::ICU()
+{
+}
+
+ICU::~ICU()
+{
+}
+
+ICU::ICU(Internal::ICU* impl)
+: BaseHandle(impl)
+{
+}
+
+ICU ICU::New()
+{
+ auto icuImpl = new Internal::ICU();
+
+ return ICU(icuImpl);
+}
+
+void ICU::UpdateLineBreakInfoByLocale(const std::string& text,
+ Length numberOfCharacters,
+ const char* locale,
+ LineBreakInfo* breakInfo)
+{
+ GetImplementation(*this).UpdateLineBreakInfoByLocale(text, numberOfCharacters, locale, breakInfo);
+}
+
+} // namespace TextAbstraction
+
+} // namespace Dali
--- /dev/null
+#ifndef DALI_PLATFORM_TEXT_ABSTRACTION_ICU_H
+#define DALI_PLATFORM_TEXT_ABSTRACTION_ICU_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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/devel-api/text-abstraction/text-abstraction-definitions.h>
+#include <dali/public-api/dali-adaptor-common.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/object/base-handle.h>
+
+namespace Dali
+{
+namespace TextAbstraction
+{
+namespace Internal DALI_INTERNAL
+{
+class ICU;
+
+} // namespace DALI_INTERNAL
+
+/**
+ * @brief To support ICU in dali. ICU, International Components for Unicode.
+ */
+class DALI_ADAPTOR_API ICU : public BaseHandle
+{
+public:
+ /**
+ * @brief Create an uninitialized ICU handle.
+ *
+ */
+ ICU();
+
+ /**
+ * @brief Destructor
+ *
+ * This is non-virtual since derived Handle types must not contain data or virtual methods.
+ */
+ ~ICU();
+
+ /**
+ * @brief This constructor is used by ICU::New().
+ *
+ * @param[in] implementation A pointer to the internal icu object.
+ */
+ explicit DALI_INTERNAL ICU(Internal::ICU* implementation);
+
+ /**
+ * @brief Create a handle to the new ICU instance.
+ *
+ * @return A handle to the ICU.
+ */
+ static ICU New();
+
+ /**
+ * @brief Update line break information by ICU.
+ * @remark Updates given line break information with ICU dictionary-based word wrap information that unibreak does not support.
+ * @param[in] text A string of UTF-8 characters.
+ * @param[in] numberOfCharacters The number of characters.
+ * @param[in] locale The locale code. (en, ko, en_US, ko_KR.utf8, etc. ICU accepts most formats of locale code), The usual expected form is language_locale (ko_KR).
+ * @param[out] breakInfo The unibreak line break information buffer.
+ */
+ void UpdateLineBreakInfoByLocale(const std::string& text,
+ Length numberOfCharacters,
+ const char* locale,
+ LineBreakInfo* breakInfo);
+};
+
+} // namespace TextAbstraction
+
+} // namespace Dali
+
+#endif // DALI_PLATFORM_TEXT_ABSTRACTION_ICU_H
${adaptor_text_dir}/text-abstraction/shaping-impl.cpp
${adaptor_text_dir}/text-abstraction/text-renderer-impl.cpp
${adaptor_text_dir}/text-abstraction/hyphenation-impl.cpp
+ ${adaptor_text_dir}/text-abstraction/icu-impl.cpp
${adaptor_text_dir}/text-abstraction/plugin/bitmap-font-cache-item.cpp
${adaptor_text_dir}/text-abstraction/plugin/embedded-item.cpp
${adaptor_text_dir}/text-abstraction/plugin/font-client-utils.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 <dali/internal/text/text-abstraction/icu-impl.h>
+
+// INTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+
+// EXTERNAL INCLUDES
+#include <dlfcn.h>
+
+namespace
+{
+const char* ICU_PLUGIN_SO("libdali2-icu-plugin.so");
+} // namespace
+
+namespace Dali
+{
+namespace TextAbstraction
+{
+namespace Internal
+{
+
+ICU::ICU()
+: mPlugin(nullptr),
+ mHandle(nullptr),
+ mCreateICUPluginPtr(nullptr),
+ mDestroyICUPluginPtr(nullptr),
+ mInitialized(false)
+{
+}
+
+ICU::~ICU()
+{
+ if(mHandle != nullptr)
+ {
+ if(mDestroyICUPluginPtr != nullptr)
+ {
+ mDestroyICUPluginPtr(mPlugin);
+ }
+ dlclose(mHandle);
+ }
+}
+
+void ICU::Initialize()
+{
+ // Try once.
+ mInitialized = true;
+
+ char* error = nullptr;
+
+ mHandle = dlopen(ICU_PLUGIN_SO, RTLD_LAZY);
+ if(mHandle == nullptr)
+ {
+ error = dlerror();
+ DALI_LOG_ERROR("ICU, dlopen error: %s\n", error ? error : "null");
+ return;
+ }
+
+ mCreateICUPluginPtr = reinterpret_cast<CreateICUPluginFunction>(dlsym(mHandle, "CreateICUPlugin"));
+ if(mCreateICUPluginPtr == nullptr)
+ {
+ error = dlerror();
+ DALI_LOG_ERROR("Can't load symbol CreateICUPlugin(), error: %s\n", error ? error : "null");
+ dlclose(mHandle);
+ mHandle = nullptr;
+ return;
+ }
+
+ mDestroyICUPluginPtr = reinterpret_cast<DestroyICUPluginFunction>(dlsym(mHandle, "DestroyICUPlugin"));
+ if(mDestroyICUPluginPtr == nullptr)
+ {
+ error = dlerror();
+ DALI_LOG_ERROR("Can't load symbol DestroyICUPlugin(), error: %s\n", error ? error : "null");
+ dlclose(mHandle);
+ mHandle = nullptr;
+ mCreateICUPluginPtr = nullptr;
+ return;
+ }
+
+ mPlugin = mCreateICUPluginPtr();
+ if(mPlugin == nullptr)
+ {
+ DALI_LOG_ERROR("Can't create the ICUPlugin object\n");
+ dlclose(mHandle);
+ mHandle = nullptr;
+ mCreateICUPluginPtr = nullptr;
+ mDestroyICUPluginPtr = nullptr;
+ return;
+ }
+}
+
+void ICU::UpdateLineBreakInfoByLocale(const std::string& text,
+ Length numberOfCharacters,
+ const char* locale,
+ LineBreakInfo* breakInfo)
+{
+ if(!mInitialized)
+ {
+ Initialize();
+ }
+ if(mPlugin != nullptr)
+ {
+ mPlugin->UpdateLineBreakInfoByLocale(text, numberOfCharacters, locale, breakInfo);
+ }
+}
+
+} // namespace Internal
+
+} // namespace TextAbstraction
+
+} // namespace Dali
--- /dev/null
+#ifndef DALI_INTERNAL_TEXT_ABSTRACTION_ICU_IMPL_H
+#define DALI_INTERNAL_TEXT_ABSTRACTION_ICU_IMPL_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/public-api/object/base-object.h>
+
+// INTERNAL INCLUDES
+#include <dali/devel-api/text-abstraction/icu-plugin.h>
+#include <dali/devel-api/text-abstraction/icu.h>
+
+namespace Dali
+{
+namespace TextAbstraction
+{
+namespace Internal
+{
+/**
+ * Implementation of the ICU
+ */
+class ICU : public BaseObject
+{
+public:
+ /**
+ * Constructor
+ */
+ ICU();
+
+ /**
+ * Destructor
+ */
+ ~ICU();
+
+ /**
+ * @brief Dali::TextAbstraction::ICU::UpdateLineBreakInfoByLocale()
+ */
+ void UpdateLineBreakInfoByLocale(const std::string& text,
+ Length numberOfCharacters,
+ const char* locale,
+ LineBreakInfo* breakInfo);
+
+private:
+ /**
+ * @brief Initializes member data and dynamically load icu-plugin.so of dali-extension.
+ */
+ void Initialize();
+
+private:
+ ICUPlugin* mPlugin; ///< icu plugin handle
+ void* mHandle; ///< Handle for the loaded library
+
+ using CreateICUPluginFunction = ICUPlugin* (*)();
+ using DestroyICUPluginFunction = void (*)(ICUPlugin* plugin);
+
+ CreateICUPluginFunction mCreateICUPluginPtr;
+ DestroyICUPluginFunction mDestroyICUPluginPtr;
+
+ bool mInitialized : 1; ///< Whether Initialize() has been called, prevents dlopen from being attempted again.
+
+private:
+ ICU(const ICU&);
+ ICU& operator=(const ICU&);
+
+}; // class ICU
+
+} // namespace Internal
+
+} // namespace TextAbstraction
+
+inline static TextAbstraction::Internal::ICU& GetImplementation(TextAbstraction::ICU& icu)
+{
+ DALI_ASSERT_ALWAYS(icu && "icu handle is empty");
+ BaseObject& handle = icu.GetBaseObject();
+ return static_cast<TextAbstraction::Internal::ICU&>(handle);
+}
+
+inline static const TextAbstraction::Internal::ICU& GetImplementation(const TextAbstraction::ICU& icu)
+{
+ DALI_ASSERT_ALWAYS(icu && "icu handle is empty");
+ const BaseObject& handle = icu.GetBaseObject();
+ return static_cast<const TextAbstraction::Internal::ICU&>(handle);
+}
+
+} // namespace Dali
+
+#endif // DALI_INTERNAL_TEXT_ABSTRACTION_ICU_IMPL_H