[dali_2.0.52] Merge branch 'devel/master' 85/266485/1
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Fri, 12 Nov 2021 10:49:19 +0000 (10:49 +0000)
committerAdeel Kazmi <adeel.kazmi@samsung.com>
Fri, 12 Nov 2021 10:49:19 +0000 (10:49 +0000)
Change-Id: I365f9c17fbd9b603024dc1704231fa6a6e95bd2f

24 files changed:
automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/accessibility-test-utils.cpp
automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/accessibility-test-utils.h
automated-tests/src/dali-toolkit-internal/utc-Dali-Accessibility-Controls-BridgeUp.cpp
automated-tests/src/dali-toolkit/utc-Dali-Transition.cpp
dali-toolkit/devel-api/controls/accessible-impl.cpp
dali-toolkit/devel-api/controls/accessible-impl.h
dali-toolkit/internal/controls/canvas-view/canvas-view-impl.cpp
dali-toolkit/internal/controls/control/control-data-impl.cpp
dali-toolkit/internal/file.list
dali-toolkit/internal/text/text-controller-impl-model-updater.cpp [new file with mode: 0644]
dali-toolkit/internal/text/text-controller-impl-model-updater.h [new file with mode: 0644]
dali-toolkit/internal/text/text-controller-impl.cpp
dali-toolkit/internal/text/text-controller-impl.h
dali-toolkit/internal/transition/transition-base-impl.cpp
dali-toolkit/internal/transition/transition-base-impl.h
dali-toolkit/internal/transition/transition-set-impl.cpp
dali-toolkit/internal/visuals/text/text-visual.cpp
dali-toolkit/internal/visuals/text/text-visual.h
dali-toolkit/public-api/dali-toolkit-version.cpp
dali-toolkit/styles/1920x1080_rpi/dali-toolkit-default-theme.json [new file with mode: 0644]
dali-toolkit/styles/1920x1080_rpi/images/cursor_handler_drop_center.png [new file with mode: 0644]
dali-toolkit/styles/1920x1080_rpi/images/selection_handle_drop_left.png [new file with mode: 0644]
dali-toolkit/styles/1920x1080_rpi/images/selection_handle_drop_right.png [new file with mode: 0644]
packaging/dali-toolkit.spec

index a9d9f03..b654d52 100644 (file)
 #include <dali/devel-api/adaptor-framework/accessibility-impl.h>
 #include "dbus-wrapper.h"
 
-namespace Dali {
-    namespace Accessibility {
-
-        using MethodType = TestDBusWrapper::MethodType;
-        using MessagePtr = DBusWrapper::MessagePtr;
-
-        static bool MoveOutedCalled = false;
-
-        void TestEnableSC(bool b) {
-            static bool firstTime = true;
-            if (b && firstTime) {
-                firstTime = false;
-                auto bridge = Accessibility::Bridge::GetCurrentBridge();
-                Dali::Stage stage = Dali::Stage::GetCurrent();
-                auto accessible = Accessibility::Accessible::Get( stage.GetRootLayer() );
-//                bridge->SetApplicationChild( accessible ); // BART
-                bridge->AddTopLevelWindow( accessible ); // BART
-                bridge->SetApplicationName( "TestApp" );
-                bridge->Initialize();
-
-                static bool ScreenReaderEnabled = false;
-                static bool IsEnabled = false;
-
-                auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
-
-                wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/bus", "org.a11y.Status", "ScreenReaderEnabled", MethodType::Getter}] = [wr](const MessagePtr &m) -> MessagePtr {
-                    auto reply = wr->newReplyMessage(m);
-                    wr->Encode(reply, std::tuple<TestDBusWrapper::Variant<bool>>{ ScreenReaderEnabled });
-                    return reply;
-                };
-                wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/bus", "org.a11y.Status", "IsEnabled", MethodType::Getter}] = [wr](const MessagePtr &m) -> MessagePtr {
-                    auto reply = wr->newReplyMessage(m);
-                    wr->Encode(reply, std::tuple<TestDBusWrapper::Variant<bool>>{ IsEnabled });
-                    return reply;
-                };
-                wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/bus", "org.a11y.Bus", "GetAddress", MethodType::Method}] = [wr](const MessagePtr &m) -> MessagePtr {
-                    auto reply = wr->newReplyMessage(m);
-                    wr->Encode(reply, std::tuple<const char*>{ "bus" });
-                    return reply;
-                };
-                wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/atspi/accessible/root", "org.a11y.atspi.Socket", "Embed", MethodType::Method}] = [wr](const MessagePtr &m) -> MessagePtr {
-                    auto reply = wr->newReplyMessage(m);
-                    wr->Encode(reply, std::tuple<Address>{ {"bus", "root"} });
-                    return reply;
-                };
-                wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/atspi/accessible", "org.a11y.atspi.Event.Object", "PropertyChange", MethodType::Method}] =
-                [wr](const MessagePtr &m) -> MessagePtr {
-                    return wr->newReplyMessage(m);
-                };
-                wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/atspi/accessible", "org.a11y.atspi.Event.Object", "StateChanged", MethodType::Method}] =
-                [wr](const MessagePtr &m) -> MessagePtr {
-                    return wr->newReplyMessage(m);
-                };
-                wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/atspi/accessible", "org.a11y.atspi.Event.Object", "BoundsChanged", MethodType::Method}] =
-                [wr](const MessagePtr &m) -> MessagePtr {
-                    return wr->newReplyMessage(m);
-                };
-                wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/atspi/accessible", "org.a11y.atspi.Event.Object", "ActiveDescendantChanged", MethodType::Method}] =
-                [wr](const MessagePtr &m) -> MessagePtr {
-                    return wr->newReplyMessage(m);
-                };
-                wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/atspi/accessible", "org.a11y.atspi.Event.Object", "TextChanged", MethodType::Method}] =
-                [wr](const MessagePtr &m) -> MessagePtr {
-                    return wr->newReplyMessage(m);
-                };
-                wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/atspi/accessible", "org.a11y.atspi.Event.Object", "TextCaretMoved", MethodType::Method}] =
-                [wr](const MessagePtr &m) -> MessagePtr {
-                    return wr->newReplyMessage(m);
-                };
-                wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/atspi/accessible", "org.a11y.atspi.Event.Object", "MoveOuted", MethodType::Method}] =
-                [wr](const MessagePtr &m) -> MessagePtr {
-                    MoveOutedCalled = true;
-                    return wr->newReplyMessage(m);
-                };
-            }
-            auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
-            wr->fromTestChangeProperty("/org/a11y/bus", "org.a11y.Status", "ScreenReaderEnabled", b);
-            wr->fromTestChangeProperty("/org/a11y/bus", "org.a11y.Status", "IsEnabled", b);
-        }
-
-        std::vector<Address> TestGetChildren(const Address &adr)
-        {
-            auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
-            auto chs = wr->fromTestCall<std::vector<Address>>(adr.GetPath(), "org.a11y.atspi.Accessible", "GetChildren", std::tuple<>());
-            return std::move(std::get<0>(chs));
-        }
-
-        std::string TestGetName(const Address &adr)
-        {
-            auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
-            auto name = wr->fromTestGet<std::string>(adr.GetPath(), "org.a11y.atspi.Accessible", "Name");
-            return name;
-        }
-
-        std::string TestGetDescription(const Address &adr)
-        {
-            auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
-            auto description = wr->fromTestGet<std::string>(adr.GetPath(), "org.a11y.atspi.Accessible", "Description");
-            return description;
-        }
-
-        uint32_t TestGetRole(const Address &adr)
-        {
-            auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
-            auto chs = wr->fromTestCall<uint32_t>(adr.GetPath(), "org.a11y.atspi.Accessible", "GetRole", std::tuple<>());
-            return std::move(std::get<0>(chs));
-        }
-
-        std::string TestGetRoleName(const Address &adr)
-        {
-            auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
-            auto chs = wr->fromTestCall<std::string>(adr.GetPath(), "org.a11y.atspi.Accessible", "GetRoleName", std::tuple<>());
-            return std::move(std::get<0>(chs));
-        }
-
-        Address TestGetParent(const Address &adr)
-        {
-            auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
-            auto chs = wr->fromTestGet< Address >(adr.GetPath(), "org.a11y.atspi.Accessible", "Parent");
-            return chs;
-        }
-
-        std::string TestGetLocalizedRoleName(const Address &adr)
-        {
-            auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
-            auto chs = wr->fromTestCall<std::string>(adr.GetPath(), "org.a11y.atspi.Accessible", "GetLocalizedRoleName", std::tuple<>());
-            return std::move(std::get<0>(chs));
-        }
-
-        std::array< uint32_t, 2 > TestGetStates(const Address &adr)
-        {
-            auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
-            auto chs = wr->fromTestCall<std::array< uint32_t, 2 >>(adr.GetPath(), "org.a11y.atspi.Accessible", "GetState", std::tuple<>());
-            return std::move(std::get<0>(chs));
-        }
-
-        std::unordered_map< std::string, std::string > TestGetAttributes(const Address &adr)
-        {
-            auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
-            auto chs = wr->fromTestCall<std::unordered_map< std::string, std::string >>(adr.GetPath(), "org.a11y.atspi.Accessible", "GetAttributes", std::tuple<>());
-            return std::move(std::get<0>(chs));
-        }
-
-        bool TestDoGesture(const Address &adr, Dali::Accessibility::Gesture type, int32_t xBeg, int32_t xEnd, int32_t yBeg, int32_t yEnd, Dali::Accessibility::GestureState state, uint32_t eventTime)
-        {
-            auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
-            auto chs = wr->fromTestCall< bool >(adr.GetPath(), "org.a11y.atspi.Accessible", "DoGesture",
-                std::tuple< Dali::Accessibility::Gesture, int32_t, int32_t, int32_t, int32_t, Dali::Accessibility::GestureState, uint32_t >(type, xBeg, xEnd, yBeg, yEnd, state, eventTime ));
-            return std::move(std::get<0>(chs));
-        }
-
-        std::vector< std::tuple< uint32_t, std::vector< Dali::Accessibility::Address > > > TestGetRelationSet(const Address &adr)
-        {
-            auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
-            auto chs = wr->fromTestCall< std::vector< std::tuple< uint32_t, std::vector< Dali::Accessibility::Address > > > >(adr.GetPath(), "org.a11y.atspi.Accessible", "GetRelationSet", std::tuple<>());
-            return std::move(std::get<0>(chs));
-        }
-
-        Address TestGetChildAtIndex(const Address &adr, int index)
-        {
-            auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
-            auto chs = wr->fromTestCall< Address >(adr.GetPath(), "org.a11y.atspi.Accessible", "GetChildAtIndex", std::tuple< int >( index ));
-            return std::move(std::get<0>(chs));
-        }
-
-        ComponentLayer TestGetLayer(const Address &adr)
-        {
-            auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
-            auto chs = wr->fromTestCall< Dali::Accessibility::ComponentLayer >(adr.GetPath(), "org.a11y.atspi.Component", "GetLayer", std::tuple<>());
-            return std::move(std::get<0>(chs));
-        }
-
-        int TestGetIndexInParent(const Address &adr)
-        {
-            auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
-            auto chs = wr->fromTestCall< int >(adr.GetPath(), "org.a11y.atspi.Accessible", "GetIndexInParent", std::tuple<>());
-            return std::move(std::get<0>(chs));
-        }
-
-        bool TestGrabFocus(const Address &adr)
-        {
-            auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
-            auto chs = wr->fromTestCall< bool >(adr.GetPath(), "org.a11y.atspi.Component", "GrabFocus", std::tuple<>());
-            return std::move(std::get<0>(chs));
-        }
-
-        bool TestGrabHighlight(const Address &adr)
-        {
-            auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
-            auto chs = wr->fromTestCall< bool >(adr.GetPath(), "org.a11y.atspi.Component", "GrabHighlight", std::tuple<>());
-            return std::move(std::get<0>(chs));
-        }
-
-        bool TestClearHighlight(const Address &adr)
-        {
-            auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
-            auto chs = wr->fromTestCall< bool >(adr.GetPath(), "org.a11y.atspi.Component", "ClearHighlight", std::tuple<>());
-            return std::move(std::get<0>(chs));
-        }
-
-        std::tuple< int32_t, int32_t, int32_t, int32_t > TestGetExtents(const Address &adr, Dali::Accessibility::CoordinateType coordinateType)
-        {
-            auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
-            auto chs = wr->fromTestCall< std::tuple< int32_t, int32_t, int32_t, int32_t > >(adr.GetPath(), "org.a11y.atspi.Component", "GetExtents", std::make_tuple(static_cast<uint32_t>(coordinateType)));
-            return std::move(std::get<0>(chs));
-        }
-
-        int TestGetMdiZOrder(const Address &adr)
-        {
-            auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
-            auto chs = wr->fromTestCall< int16_t >(adr.GetPath(), "org.a11y.atspi.Component", "GetMDIZOrder", std::tuple<>());
-            return std::move(std::get<0>(chs));
-        }
-
-        double TestGetAlpha(const Address &adr)
-        {
-            auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
-            auto chs = wr->fromTestCall< double >(adr.GetPath(), "org.a11y.atspi.Component", "GetAlpha", std::tuple<>());
-            return std::move(std::get<0>(chs));
-        }
-
-        std::string TestGetActionName( const Address &adr, size_t index )
-        {
-            auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
-            auto chs = wr->fromTestCall< std::string >(adr.GetPath(), "org.a11y.atspi.Action", "GetName", std::tuple< int32_t >( index ));
-            return std::move(std::get<0>(chs));
-        }
-
-        std::string TestGetLocalizedActionName( const Address &adr, size_t index )
-        {
-            auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
-            auto chs = wr->fromTestCall< std::string >(adr.GetPath(), "org.a11y.atspi.Action", "GetLocalizedName", std::tuple< int32_t >( index ));
-            return std::move(std::get<0>(chs));
-        }
-
-        size_t TestGetActionCount( const Address &adr )
-        {
-            auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
-            auto count = wr->fromTestGet< int32_t >(adr.GetPath(), "org.a11y.atspi.Action", "NActions");
-            return count;
-        }
-
-        bool TestDoAction ( const Address &adr, size_t index )
-        {
-            auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
-            auto chs = wr->fromTestCall< bool >(adr.GetPath(), "org.a11y.atspi.Action", "DoAction", std::tuple< int32_t >( index ));
-            return std::move(std::get<0>(chs));
-        }
-
-        bool TestDoAction ( const Address &adr, const std::string& name )
-        {
-            auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
-            auto chs = wr->fromTestCall< bool >(adr.GetPath(), "org.a11y.atspi.Action", "DoActionName", std::tuple< std::string >( name ));
-            return std::move(std::get<0>(chs));
-        }
-
-        std::string TestGetActionKeyBinding ( const Address &adr, size_t index )
-        {
-            auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
-            auto chs = wr->fromTestCall< std::string >(adr.GetPath(), "org.a11y.atspi.Action", "GetKeyBinding", std::tuple< int32_t >( index ));
-            return std::move(std::get<0>(chs));
-        }
-
-        std::string TestGetActionDescription ( const Address &adr, size_t index )
-        {
-            auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
-            auto chs = wr->fromTestCall< std::string >(adr.GetPath(), "org.a11y.atspi.Action", "GetDescription", std::tuple< int32_t >( index ));
-            return std::move(std::get<0>(chs));
-        }
-
-        void TestResetMoveOutedCalled ()
-        {
-          MoveOutedCalled = false;
-        }
-
-        bool TestGetMoveOutedCalled ()
-        {
-          return MoveOutedCalled;
-        }
-
-        void printTree(const Address &root, size_t depth)
-        {
-            auto name = TestGetName(root);
-            printf("%10s", root.GetPath().c_str());
-            for(unsigned int i = 0; i < depth; ++i) printf("  ");
-            printf("%s\n", name.c_str());
-            auto chs = TestGetChildren(root);
-            for(auto &c : chs)
-                printTree(c, depth + 1);
-        }
-
-        bool Find( const std::vector< std::string > &collection, const std::string &key)
-        {
-            for ( auto& it : collection)
-                if( it == key )
-                    return true;
-            return false;
-        }
+namespace Dali
+{
+namespace Accessibility
+{
+  using MethodType = TestDBusWrapper::MethodType;
+  using MessagePtr = DBusWrapper::MessagePtr;
+
+  static bool gMoveOutedCalled = false;
+
+  void TestEnableSC(bool b)
+  {
+    static bool firstTime = true;
+    if (b && firstTime)
+    {
+      firstTime = false;
+      auto bridge = Accessibility::Bridge::GetCurrentBridge();
+      Dali::Stage stage = Dali::Stage::GetCurrent();
+      auto accessible = Accessibility::Accessible::Get( stage.GetRootLayer(), true );
+      bridge->AddTopLevelWindow( accessible );
+      bridge->SetApplicationName( "TestApp" );
+      bridge->Initialize();
+
+      static bool ScreenReaderEnabled = false;
+      static bool IsEnabled = false;
+
+      auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+
+      wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/bus", "org.a11y.Status", "ScreenReaderEnabled", MethodType::Getter}] = [wr](const MessagePtr &m) -> MessagePtr {
+          auto reply = wr->newReplyMessage(m);
+          wr->Encode(reply, std::tuple<TestDBusWrapper::Variant<bool>>{ ScreenReaderEnabled });
+          return reply;
+      };
+      wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/bus", "org.a11y.Status", "IsEnabled", MethodType::Getter}] = [wr](const MessagePtr &m) -> MessagePtr {
+          auto reply = wr->newReplyMessage(m);
+          wr->Encode(reply, std::tuple<TestDBusWrapper::Variant<bool>>{ IsEnabled });
+          return reply;
+      };
+      wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/bus", "org.a11y.Bus", "GetAddress", MethodType::Method}] = [wr](const MessagePtr &m) -> MessagePtr {
+          auto reply = wr->newReplyMessage(m);
+          wr->Encode(reply, std::tuple<const char*>{ "bus" });
+          return reply;
+      };
+      wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/atspi/accessible/root", "org.a11y.atspi.Socket", "Embed", MethodType::Method}] = [wr](const MessagePtr &m) -> MessagePtr {
+          auto reply = wr->newReplyMessage(m);
+          wr->Encode(reply, std::tuple<Address>{ {"bus", "root"} });
+          return reply;
+      };
+      wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/atspi/accessible", "org.a11y.atspi.Event.Object", "PropertyChange", MethodType::Method}] =
+      [wr](const MessagePtr &m) -> MessagePtr {
+          return wr->newReplyMessage(m);
+      };
+      wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/atspi/accessible", "org.a11y.atspi.Event.Object", "StateChanged", MethodType::Method}] =
+      [wr](const MessagePtr &m) -> MessagePtr {
+          return wr->newReplyMessage(m);
+      };
+      wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/atspi/accessible", "org.a11y.atspi.Event.Object", "BoundsChanged", MethodType::Method}] =
+      [wr](const MessagePtr &m) -> MessagePtr {
+          return wr->newReplyMessage(m);
+      };
+      wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/atspi/accessible", "org.a11y.atspi.Event.Object", "ActiveDescendantChanged", MethodType::Method}] =
+      [wr](const MessagePtr &m) -> MessagePtr {
+          return wr->newReplyMessage(m);
+      };
+      wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/atspi/accessible", "org.a11y.atspi.Event.Object", "TextChanged", MethodType::Method}] =
+      [wr](const MessagePtr &m) -> MessagePtr {
+          return wr->newReplyMessage(m);
+      };
+      wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/atspi/accessible", "org.a11y.atspi.Event.Object", "TextCaretMoved", MethodType::Method}] =
+      [wr](const MessagePtr &m) -> MessagePtr {
+          return wr->newReplyMessage(m);
+      };
+      wr->testMethods[std::tuple<std::string, std::string, std::string, MethodType>{"/org/a11y/atspi/accessible", "org.a11y.atspi.Event.Object", "MoveOuted", MethodType::Method}] =
+      [wr](const MessagePtr &m) -> MessagePtr {
+          gMoveOutedCalled = true;
+          return wr->newReplyMessage(m);
+      };
     }
-}
+    auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+    wr->fromTestChangeProperty("/org/a11y/bus", "org.a11y.Status", "ScreenReaderEnabled", b);
+    wr->fromTestChangeProperty("/org/a11y/bus", "org.a11y.Status", "IsEnabled", b);
+  }
+
+  std::vector<Address> TestGetChildren(const Address &adr)
+  {
+    auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+    auto chs = wr->fromTestCall<std::vector<Address>>(adr.GetPath(), "org.a11y.atspi.Accessible", "GetChildren", std::tuple<>());
+    return std::move(std::get<0>(chs));
+  }
+
+  std::string TestGetName(const Address &adr)
+  {
+    auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+    auto name = wr->fromTestGet<std::string>(adr.GetPath(), "org.a11y.atspi.Accessible", "Name");
+    return name;
+  }
+
+  std::string TestGetDescription(const Address &adr)
+  {
+    auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+    auto description = wr->fromTestGet<std::string>(adr.GetPath(), "org.a11y.atspi.Accessible", "Description");
+    return description;
+  }
+
+  uint32_t TestGetRole(const Address &adr)
+  {
+    auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+    auto chs = wr->fromTestCall<uint32_t>(adr.GetPath(), "org.a11y.atspi.Accessible", "GetRole", std::tuple<>());
+    return std::move(std::get<0>(chs));
+  }
+
+  std::string TestGetRoleName(const Address &adr)
+  {
+    auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+    auto chs = wr->fromTestCall<std::string>(adr.GetPath(), "org.a11y.atspi.Accessible", "GetRoleName", std::tuple<>());
+    return std::move(std::get<0>(chs));
+  }
+
+  Address TestGetParent(const Address &adr)
+  {
+    auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+    auto chs = wr->fromTestGet< Address >(adr.GetPath(), "org.a11y.atspi.Accessible", "Parent");
+    return chs;
+  }
+
+  std::string TestGetLocalizedRoleName(const Address &adr)
+  {
+    auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+    auto chs = wr->fromTestCall<std::string>(adr.GetPath(), "org.a11y.atspi.Accessible", "GetLocalizedRoleName", std::tuple<>());
+    return std::move(std::get<0>(chs));
+  }
+
+  std::array< uint32_t, 2 > TestGetStates(const Address &adr)
+  {
+    auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+    auto chs = wr->fromTestCall<std::array< uint32_t, 2 >>(adr.GetPath(), "org.a11y.atspi.Accessible", "GetState", std::tuple<>());
+    return std::move(std::get<0>(chs));
+  }
+
+  std::unordered_map< std::string, std::string > TestGetAttributes(const Address &adr)
+  {
+    auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+    auto chs = wr->fromTestCall<std::unordered_map< std::string, std::string >>(adr.GetPath(), "org.a11y.atspi.Accessible", "GetAttributes", std::tuple<>());
+    return std::move(std::get<0>(chs));
+  }
+
+  bool TestDoGesture(const Address &adr, Dali::Accessibility::Gesture type, int32_t xBeg, int32_t xEnd, int32_t yBeg, int32_t yEnd, Dali::Accessibility::GestureState state, uint32_t eventTime)
+  {
+    auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+    auto chs = wr->fromTestCall< bool >(adr.GetPath(), "org.a11y.atspi.Accessible", "DoGesture",
+        std::tuple< Dali::Accessibility::Gesture, int32_t, int32_t, int32_t, int32_t, Dali::Accessibility::GestureState, uint32_t >(type, xBeg, xEnd, yBeg, yEnd, state, eventTime ));
+    return std::move(std::get<0>(chs));
+  }
+
+  std::vector< std::tuple< uint32_t, std::vector< Dali::Accessibility::Address > > > TestGetRelationSet(const Address &adr)
+  {
+    auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+    auto chs = wr->fromTestCall< std::vector< std::tuple< uint32_t, std::vector< Dali::Accessibility::Address > > > >(adr.GetPath(), "org.a11y.atspi.Accessible", "GetRelationSet", std::tuple<>());
+    return std::move(std::get<0>(chs));
+  }
+
+  Address TestGetChildAtIndex(const Address &adr, int index)
+  {
+    auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+    auto chs = wr->fromTestCall< Address >(adr.GetPath(), "org.a11y.atspi.Accessible", "GetChildAtIndex", std::tuple< int >( index ));
+    return std::move(std::get<0>(chs));
+  }
+
+  ComponentLayer TestGetLayer(const Address &adr)
+  {
+    auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+    auto chs = wr->fromTestCall< Dali::Accessibility::ComponentLayer >(adr.GetPath(), "org.a11y.atspi.Component", "GetLayer", std::tuple<>());
+    return std::move(std::get<0>(chs));
+  }
+
+  int TestGetIndexInParent(const Address &adr)
+  {
+    auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+    auto chs = wr->fromTestCall< int >(adr.GetPath(), "org.a11y.atspi.Accessible", "GetIndexInParent", std::tuple<>());
+    return std::move(std::get<0>(chs));
+  }
+
+  bool TestGrabFocus(const Address &adr)
+  {
+    auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+    auto chs = wr->fromTestCall< bool >(adr.GetPath(), "org.a11y.atspi.Component", "GrabFocus", std::tuple<>());
+    return std::move(std::get<0>(chs));
+  }
+
+  bool TestGrabHighlight(const Address &adr)
+  {
+    auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+    auto chs = wr->fromTestCall< bool >(adr.GetPath(), "org.a11y.atspi.Component", "GrabHighlight", std::tuple<>());
+    return std::move(std::get<0>(chs));
+  }
+
+  bool TestClearHighlight(const Address &adr)
+  {
+    auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+    auto chs = wr->fromTestCall< bool >(adr.GetPath(), "org.a11y.atspi.Component", "ClearHighlight", std::tuple<>());
+    return std::move(std::get<0>(chs));
+  }
+
+  std::tuple< int32_t, int32_t, int32_t, int32_t > TestGetExtents(const Address &adr, Dali::Accessibility::CoordinateType coordinateType)
+  {
+    auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+    auto chs = wr->fromTestCall< std::tuple< int32_t, int32_t, int32_t, int32_t > >(adr.GetPath(), "org.a11y.atspi.Component", "GetExtents", std::make_tuple(static_cast<uint32_t>(coordinateType)));
+    return std::move(std::get<0>(chs));
+  }
+
+  int TestGetMdiZOrder(const Address &adr)
+  {
+    auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+    auto chs = wr->fromTestCall< int16_t >(adr.GetPath(), "org.a11y.atspi.Component", "GetMDIZOrder", std::tuple<>());
+    return std::move(std::get<0>(chs));
+  }
+
+  double TestGetAlpha(const Address &adr)
+  {
+    auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+    auto chs = wr->fromTestCall< double >(adr.GetPath(), "org.a11y.atspi.Component", "GetAlpha", std::tuple<>());
+    return std::move(std::get<0>(chs));
+  }
+
+  std::string TestGetActionName(const Address &adr, size_t index)
+  {
+    auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+    auto chs = wr->fromTestCall< std::string >(adr.GetPath(), "org.a11y.atspi.Action", "GetName", std::tuple< int32_t >( index ));
+    return std::move(std::get<0>(chs));
+  }
+
+  std::string TestGetLocalizedActionName(const Address &adr, size_t index)
+  {
+    auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+    auto chs = wr->fromTestCall< std::string >(adr.GetPath(), "org.a11y.atspi.Action", "GetLocalizedName", std::tuple< int32_t >( index ));
+    return std::move(std::get<0>(chs));
+  }
+
+  size_t TestGetActionCount(const Address &adr)
+  {
+    auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+    auto count = wr->fromTestGet< int32_t >(adr.GetPath(), "org.a11y.atspi.Action", "NActions");
+    return count;
+  }
+
+  bool TestDoAction(const Address &adr, size_t index)
+  {
+    auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+    auto chs = wr->fromTestCall< bool >(adr.GetPath(), "org.a11y.atspi.Action", "DoAction", std::tuple< int32_t >( index ));
+    return std::move(std::get<0>(chs));
+  }
+
+  bool TestDoAction(const Address &adr, const std::string& name)
+  {
+    auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+    auto chs = wr->fromTestCall< bool >(adr.GetPath(), "org.a11y.atspi.Action", "DoActionName", std::tuple< std::string >( name ));
+    return std::move(std::get<0>(chs));
+  }
+
+  std::string TestGetActionKeyBinding(const Address &adr, size_t index)
+  {
+    auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+    auto chs = wr->fromTestCall< std::string >(adr.GetPath(), "org.a11y.atspi.Action", "GetKeyBinding", std::tuple< int32_t >( index ));
+    return std::move(std::get<0>(chs));
+  }
+
+  std::string TestGetActionDescription(const Address &adr, size_t index)
+  {
+    auto wr = static_cast<TestDBusWrapper*>(DBusWrapper::Installed());
+    auto chs = wr->fromTestCall< std::string >(adr.GetPath(), "org.a11y.atspi.Action", "GetDescription", std::tuple< int32_t >( index ));
+    return std::move(std::get<0>(chs));
+  }
+
+  void TestResetMoveOutedCalled ()
+  {
+    gMoveOutedCalled = false;
+  }
+
+  bool TestGetMoveOutedCalled ()
+  {
+    return gMoveOutedCalled;
+  }
+
+  void PrintTree(const Address &root, size_t depth)
+  {
+    auto name = TestGetName(root);
+    printf("%10s", root.GetPath().c_str());
+    for(unsigned int i = 0; i < depth; ++i) printf("  ");
+    printf("%s\n", name.c_str());
+    auto chs = TestGetChildren(root);
+    for(auto &c : chs)
+    {
+      PrintTree(c, depth + 1);
+    }
+  }
+
+  bool Find(const std::vector< std::string > &collection, const std::string &key)
+  {
+    for(auto& it : collection)
+    {
+      if(it == key)
+      {
+        return true;
+      }
+    }
+    return false;
+  }
+
+} // namespace Accessibility
+} // namespace Dali
index 6c172fd..92388e2 100644 (file)
@@ -3,42 +3,43 @@
 
 #include <dali/devel-api/adaptor-framework/accessibility.h>
 
-
-namespace Dali {
-    namespace Accessibility {
-        void TestEnableSC(bool b);
-        std::vector<Address> TestGetChildren(const Address &adr);
-        std::string TestGetName(const Address &adr);
-        std::string TestGetDescription(const Address &adr);
-        uint32_t TestGetRole(const Address &adr);
-        std::string TestGetRoleName(const Address &adr);
-        Address TestGetParent(const Address &adr);
-        std::string TestGetLocalizedRoleName(const Address &adr);
-        std::array< uint32_t, 2 > TestGetStates(const Address &adr);
-        std::unordered_map< std::string, std::string > TestGetAttributes(const Address &adr);
-        bool TestDoGesture(const Address &adr, Dali::Accessibility::Gesture type, int32_t xBeg, int32_t xEnd, int32_t yBeg, int32_t yEnd, Dali::Accessibility::GestureState state, uint32_t eventTime);
-        std::vector< std::tuple< uint32_t, std::vector< Dali::Accessibility::Address > > > TestGetRelationSet(const Address &adr);
-        Address TestGetChildAtIndex(const Address &adr, int index);
-        ComponentLayer TestGetLayer(const Address &adr);
-        int TestGetIndexInParent(const Address &adr);
-        bool TestGrabFocus(const Address &adr);
-        bool TestGrabHighlight(const Address &adr);
-        bool TestClearHighlight(const Address &adr);
-        std::tuple< int32_t, int32_t, int32_t, int32_t > TestGetExtents(const Address &adr, Dali::Accessibility::CoordinateType coordinateType );
-        int TestGetMdiZOrder(const Address &adr);
-        double TestGetAlpha(const Address &adr);
-        void printTree(const Address &root, size_t depth = 0);
-        bool Find( const std::vector< std::string > &collection, const std::string &key);
-        std::string TestGetActionName( const Address &adr, size_t index );
-        std::string TestGetLocalizedActionName( const Address &adr, size_t index );
-        size_t TestGetActionCount( const Address &adr );
-        bool TestDoAction ( const Address &adr, size_t index );
-        bool TestDoAction ( const Address &adr, const std::string& name );
-        std::string TestGetActionKeyBinding ( const Address &adr, size_t index );
-        std::string TestGetActionDescription ( const Address &adr, size_t index );
-        void TestResetMoveOutedCalled ();
-        bool TestGetMoveOutedCalled ();
-    }
-}
+namespace Dali
+{
+namespace Accessibility
+{
+  void TestEnableSC(bool b);
+  std::vector<Address> TestGetChildren(const Address &adr);
+  std::string TestGetName(const Address &adr);
+  std::string TestGetDescription(const Address &adr);
+  uint32_t TestGetRole(const Address &adr);
+  std::string TestGetRoleName(const Address &adr);
+  Address TestGetParent(const Address &adr);
+  std::string TestGetLocalizedRoleName(const Address &adr);
+  std::array< uint32_t, 2 > TestGetStates(const Address &adr);
+  std::unordered_map< std::string, std::string > TestGetAttributes(const Address &adr);
+  bool TestDoGesture(const Address &adr, Dali::Accessibility::Gesture type, int32_t xBeg, int32_t xEnd, int32_t yBeg, int32_t yEnd, Dali::Accessibility::GestureState state, uint32_t eventTime);
+  std::vector< std::tuple< uint32_t, std::vector< Dali::Accessibility::Address > > > TestGetRelationSet(const Address &adr);
+  Address TestGetChildAtIndex(const Address &adr, int index);
+  ComponentLayer TestGetLayer(const Address &adr);
+  int TestGetIndexInParent(const Address &adr);
+  bool TestGrabFocus(const Address &adr);
+  bool TestGrabHighlight(const Address &adr);
+  bool TestClearHighlight(const Address &adr);
+  std::tuple< int32_t, int32_t, int32_t, int32_t > TestGetExtents(const Address &adr, Dali::Accessibility::CoordinateType coordinateType );
+  int TestGetMdiZOrder(const Address &adr);
+  double TestGetAlpha(const Address &adr);
+  void PrintTree(const Address &root, size_t depth = 0);
+  bool Find( const std::vector< std::string > &collection, const std::string &key);
+  std::string TestGetActionName( const Address &adr, size_t index );
+  std::string TestGetLocalizedActionName( const Address &adr, size_t index );
+  size_t TestGetActionCount( const Address &adr );
+  bool TestDoAction ( const Address &adr, size_t index );
+  bool TestDoAction ( const Address &adr, const std::string& name );
+  std::string TestGetActionKeyBinding ( const Address &adr, size_t index );
+  std::string TestGetActionDescription ( const Address &adr, size_t index );
+  void TestResetMoveOutedCalled ();
+  bool TestGetMoveOutedCalled ();
+} // namespace Accessibility
+} // namespace Dali
 
 #endif //__DALI_TOOLKIT_ACCESSIBILITY_TEST_UTILS__
index 0b1ec0e..047018d 100644 (file)
@@ -1157,6 +1157,7 @@ int UtcDaliAccessibilityScrollToChildNonScrollable(void)
 
   DALI_TEST_EQUALS(accessible->IsScrollable(), false, TEST_LOCATION);
   DALI_TEST_EQUALS(accessible->ScrollToChild({}), false, TEST_LOCATION);
+  DALI_TEST_EQUALS(accessible->GetInternalActor(), Dali::Actor{}, TEST_LOCATION);
 
   Dali::Accessibility::TestEnableSC( false );
   END_TEST;
index ef1eb2c..0ead710 100755 (executable)
@@ -24,6 +24,8 @@
 #include <dali-toolkit/public-api/transition/transition-set.h>
 #include <dali-toolkit/public-api/transition/transition-base.h>
 #include <dali-toolkit/public-api/transition/transition.h>
+#include <dali-toolkit/public-api/transition/fade-transition.h>
+#include <dali-toolkit/public-api/transition/slide-transition.h>
 
 using namespace Dali;
 using namespace Dali::Toolkit;
@@ -1186,3 +1188,82 @@ int UtcDaliTransitionBetweenControlPairWithTreeWithoutScaleInheritance(void)
 
   END_TEST;
 }
+
+
+int UtcDaliMultipleTransitionAppearing(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliMultipleTransitionAppearing");
+
+  Control control = Control::New();
+  control.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
+  control.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+  control.SetProperty(Actor::Property::POSITION, Vector3(100, 200, 0));
+  control.SetProperty(Actor::Property::SIZE, Vector3(150, 150, 0));
+  Property::Map controlProperty;
+  controlProperty.Insert(Toolkit::Visual::Property::TYPE, Toolkit::Visual::COLOR);
+  controlProperty.Insert(Toolkit::ColorVisual::Property::MIX_COLOR, Vector4(1.0f, 0.0f, 0.0f, 1.0f));
+  control.SetProperty(Toolkit::Control::Property::BACKGROUND, controlProperty);
+
+  application.GetScene().Add(control);
+
+  application.SendNotification();
+  application.Render(20);
+
+  DALI_TEST_EQUALS(1.0f, control.GetCurrentProperty<float>(Actor::Property::OPACITY), TEST_LOCATION);
+
+  TransitionSet transitionSet = TransitionSet::New();
+  FadeTransition fade = FadeTransition::New(control, 0.5, TimePeriod(1.0f, 1.0f));
+  fade.SetAppearingTransition(true); // set fade in
+  transitionSet.AddTransition(fade);
+  SlideTransition slide = SlideTransition::New(control, Dali::Toolkit::SlideTransitionDirection::BOTTOM, TimePeriod(0.5f, 1.0f));
+  slide.SetAppearingTransition(true); // set slide
+  transitionSet.AddTransition(slide);
+  transitionSet.Play();
+
+  bool signalReceived(false);
+  TransitionFinishCheck finishCheck(signalReceived);
+  transitionSet.FinishedSignal().Connect(&application, finishCheck);
+
+  application.SendNotification();
+  application.Render(300);
+
+  float currentOpacity = control.GetCurrentProperty<float>(Actor::Property::OPACITY);
+  DALI_TEST_CHECK(currentOpacity == 0.0f);
+
+  application.SendNotification();
+  application.Render(400);
+
+  currentOpacity = control.GetCurrentProperty<float>(Actor::Property::OPACITY);
+  DALI_TEST_CHECK(currentOpacity == 0.5f);
+
+  application.SendNotification();
+  application.Render(500);
+
+  currentOpacity = control.GetCurrentProperty<float>(Actor::Property::OPACITY);
+  DALI_TEST_CHECK(currentOpacity > 0.5f && currentOpacity < 1.0f);
+
+  application.SendNotification();
+  application.Render(500);
+
+  currentOpacity = control.GetCurrentProperty<float>(Actor::Property::OPACITY);
+  DALI_TEST_CHECK(currentOpacity > 0.5f && currentOpacity < 1.0f);
+
+  // We didn't expect the animation to finish yet
+  application.SendNotification();
+  finishCheck.CheckSignalNotReceived();
+
+  application.SendNotification();
+  application.Render(500);
+
+  // We did expect the animation to finish
+  application.SendNotification();
+  finishCheck.CheckSignalReceived();
+
+  application.SendNotification();
+  application.Render(20);
+
+  DALI_TEST_EQUALS(1.0f, control.GetCurrentProperty<float>(Actor::Property::OPACITY), TEST_LOCATION);
+
+  END_TEST;
+}
index 9f1c78e..bd4a649 100644 (file)
@@ -542,6 +542,11 @@ std::vector<Dali::Accessibility::Relation> AccessibleImpl::GetRelationSet()
   return ret;
 }
 
+Dali::Actor AccessibleImpl::GetInternalActor()
+{
+  return Dali::Actor{};
+}
+
 bool AccessibleImpl::ScrollToChild(Actor child)
 {
   return false;
index aa5084a..18b77f5 100644 (file)
@@ -226,6 +226,11 @@ public:
   std::vector<Dali::Accessibility::Relation> GetRelationSet() override;
 
   /**
+   * @copydoc Dali::Accessibility::Accessible::GetInternalActor()
+   */
+  Dali::Actor GetInternalActor() override;
+
+  /**
    * @copydoc Dali::Accessibility::Accessible::GetStates()
    */
   virtual Dali::Accessibility::States CalculateStates();
index 1540b02..e8fefbf 100644 (file)
@@ -23,6 +23,7 @@
 #include <dali/integration-api/adaptor-framework/adaptor.h>
 #include <dali/public-api/object/type-registry-helper.h>
 #include <dali/public-api/object/type-registry.h>
+#include <dali/devel-api/rendering/texture-devel.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/devel-api/controls/control-devel.h>
@@ -202,10 +203,14 @@ void CanvasView::ApplyRasterizedImage(Texture rasterizedTexture)
   {
     if(!mTextureSet)
     {
+      std::string fragmentShader = SHADER_CANVAS_VIEW_FRAG.data();
+      DevelTexture::ApplyNativeFragmentShader(rasterizedTexture, fragmentShader);
+
       mTextureSet       = TextureSet::New();
       Geometry geometry = VisualFactoryCache::CreateQuadGeometry();
-      Shader   shader   = Shader::New(SHADER_CANVAS_VIEW_VERT, SHADER_CANVAS_VIEW_FRAG);
+      Shader   shader   = Shader::New(SHADER_CANVAS_VIEW_VERT, fragmentShader);
       Renderer renderer = Renderer::New(geometry, shader);
+
       renderer.SetTextures(mTextureSet);
       renderer.SetProperty(Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, true);
       Self().AddRenderer(renderer);
index b81149c..d9a554e 100644 (file)
@@ -507,7 +507,7 @@ Control::Impl::Impl(Control& controlImpl)
   mNeedToEmitResourceReady(false),
   mDispatchKeyEvents(true)
 {
-  Dali::Accessibility::Accessible::RegisterControlAccessibilityGetter(
+  Dali::Accessibility::Accessible::RegisterExternalAccessibleGetter(
     [](Dali::Actor actor) -> Dali::Accessibility::Accessible* {
       return Control::Impl::GetAccessibilityObject(actor);
     });
index e774545..3229006 100644 (file)
@@ -159,6 +159,7 @@ SET( toolkit_src_files
    ${toolkit_src_dir}/text/text-controller-event-handler.cpp
    ${toolkit_src_dir}/text/text-controller-impl.cpp
    ${toolkit_src_dir}/text/text-controller-impl-event-handler.cpp
+   ${toolkit_src_dir}/text/text-controller-impl-model-updater.cpp
    ${toolkit_src_dir}/text/text-controller-input-font-handler.cpp
    ${toolkit_src_dir}/text/text-controller-placeholder-handler.cpp
    ${toolkit_src_dir}/text/text-controller-relayouter.cpp
diff --git a/dali-toolkit/internal/text/text-controller-impl-model-updater.cpp b/dali-toolkit/internal/text/text-controller-impl-model-updater.cpp
new file mode 100644 (file)
index 0000000..1ce7516
--- /dev/null
@@ -0,0 +1,589 @@
+/*
+ * Copyright (c) 2021 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-toolkit/internal/text/text-controller-impl-model-updater.h>
+
+// EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/bidirectional-support.h>
+#include <dali-toolkit/internal/text/character-set-conversion.h>
+#include <dali-toolkit/internal/text/color-segmentation.h>
+#include <dali-toolkit/internal/text/hyphenator.h>
+#include <dali-toolkit/internal/text/multi-language-support.h>
+#include <dali-toolkit/internal/text/segmentation.h>
+#include <dali-toolkit/internal/text/shaper.h>
+#include <dali-toolkit/internal/text/text-editable-control-interface.h>
+
+namespace Dali::Toolkit::Text
+{
+
+namespace
+{
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_CONTROLS");
+#endif
+
+// The relative luminance of a color is defined as (L = 0.2126 * R + 0.7152 * G + 0.0722 * B)
+// based on W3C Recommendations (https://www.w3.org/TR/WCAG20/)
+constexpr float         BRIGHTNESS_THRESHOLD = 0.179f;
+constexpr float         CONSTANT_R           = 0.2126f;
+constexpr float         CONSTANT_G           = 0.7152f;
+constexpr float         CONSTANT_B           = 0.0722f;
+constexpr Dali::Vector4 BLACK(0.f, 0.f, 0.f, 1.f);
+constexpr Dali::Vector4 WHITE(1.f, 1.f, 1.f, 1.f);
+constexpr Dali::Vector4 LIGHT_BLUE(0.75f, 0.96f, 1.f, 1.f);
+constexpr Dali::Vector4 BACKGROUND_SUB4(0.58f, 0.87f, 0.96f, 1.f);
+constexpr Dali::Vector4 BACKGROUND_SUB5(0.83f, 0.94f, 0.98f, 1.f);
+constexpr Dali::Vector4 BACKGROUND_SUB6(1.f, 0.5f, 0.5f, 1.f);
+constexpr Dali::Vector4 BACKGROUND_SUB7(1.f, 0.8f, 0.8f, 1.f);
+} // namespace
+
+bool ControllerImplModelUpdater::Update(Controller::Impl& impl, OperationsMask operationsRequired)
+{
+  DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::UpdateModel\n");
+
+  // Calculate the operations to be done.
+  const OperationsMask operations = static_cast<OperationsMask>(impl.mOperationsPending & operationsRequired);
+
+  if(Controller::NO_OPERATION == operations)
+  {
+    // Nothing to do if no operations are pending and required.
+    return false;
+  }
+
+  Vector<Character>& srcCharacters = impl.mModel->mLogicalModel->mText;
+  Vector<Character>  displayCharacters;
+  bool               useHiddenText = false;
+  if(impl.mHiddenInput && impl.mEventData != nullptr && !impl.mEventData->mIsShowingPlaceholderText)
+  {
+    impl.mHiddenInput->Substitute(srcCharacters, displayCharacters);
+    useHiddenText = true;
+  }
+
+  Vector<Character>& utf32Characters    = useHiddenText ? displayCharacters : srcCharacters;
+  const Length       numberOfCharacters = utf32Characters.Count();
+
+  // Index to the first character of the first paragraph to be updated.
+  CharacterIndex startIndex = 0u;
+  // Number of characters of the paragraphs to be removed.
+  Length paragraphCharacters = 0u;
+
+  impl.CalculateTextUpdateIndices(paragraphCharacters);
+
+  // Check whether the indices for updating the text is valid
+  if(numberOfCharacters > 0u &&
+     (impl.mTextUpdateInfo.mParagraphCharacterIndex > numberOfCharacters ||
+         impl.mTextUpdateInfo.mRequestedNumberOfCharacters > numberOfCharacters))
+  {
+    std::string currentText;
+    Utf32ToUtf8(impl.mModel->mLogicalModel->mText.Begin(), numberOfCharacters, currentText);
+
+    DALI_LOG_ERROR("Controller::Impl::UpdateModel: mTextUpdateInfo has invalid indices\n");
+    DALI_LOG_ERROR("Number of characters: %d, current text is: %s\n", numberOfCharacters, currentText.c_str());
+
+    // Dump mTextUpdateInfo
+    DALI_LOG_ERROR("Dump mTextUpdateInfo:\n");
+    DALI_LOG_ERROR("     mTextUpdateInfo.mCharacterIndex = %u\n", impl.mTextUpdateInfo.mCharacterIndex);
+    DALI_LOG_ERROR("     mTextUpdateInfo.mNumberOfCharactersToRemove = %u\n", impl.mTextUpdateInfo.mNumberOfCharactersToRemove);
+    DALI_LOG_ERROR("     mTextUpdateInfo.mNumberOfCharactersToAdd = %u\n", impl.mTextUpdateInfo.mNumberOfCharactersToAdd);
+    DALI_LOG_ERROR("     mTextUpdateInfo.mPreviousNumberOfCharacters = %u\n", impl.mTextUpdateInfo.mPreviousNumberOfCharacters);
+    DALI_LOG_ERROR("     mTextUpdateInfo.mParagraphCharacterIndex = %u\n", impl.mTextUpdateInfo.mParagraphCharacterIndex);
+    DALI_LOG_ERROR("     mTextUpdateInfo.mRequestedNumberOfCharacters = %u\n", impl.mTextUpdateInfo.mRequestedNumberOfCharacters);
+    DALI_LOG_ERROR("     mTextUpdateInfo.mStartGlyphIndex = %u\n", impl.mTextUpdateInfo.mStartGlyphIndex);
+    DALI_LOG_ERROR("     mTextUpdateInfo.mStartLineIndex = %u\n", impl.mTextUpdateInfo.mStartLineIndex);
+    DALI_LOG_ERROR("     mTextUpdateInfo.mEstimatedNumberOfLines = %u\n", impl.mTextUpdateInfo.mEstimatedNumberOfLines);
+    DALI_LOG_ERROR("     mTextUpdateInfo.mClearAll = %d\n", impl.mTextUpdateInfo.mClearAll);
+    DALI_LOG_ERROR("     mTextUpdateInfo.mFullRelayoutNeeded = %d\n", impl.mTextUpdateInfo.mFullRelayoutNeeded);
+    DALI_LOG_ERROR("     mTextUpdateInfo.mIsLastCharacterNewParagraph = %d\n", impl.mTextUpdateInfo.mIsLastCharacterNewParagraph);
+
+    return false;
+  }
+
+  startIndex = impl.mTextUpdateInfo.mParagraphCharacterIndex;
+
+  if(impl.mTextUpdateInfo.mClearAll ||
+     (0u != paragraphCharacters))
+  {
+    impl.ClearModelData(startIndex, startIndex + ((paragraphCharacters > 0u) ? paragraphCharacters - 1u : 0u), operations);
+  }
+
+  impl.mTextUpdateInfo.mClearAll = false;
+
+  // Whether the model is updated.
+  bool updated = false;
+
+  Vector<LineBreakInfo>& lineBreakInfo               = impl.mModel->mLogicalModel->mLineBreakInfo;
+  const Length           requestedNumberOfCharacters = impl.mTextUpdateInfo.mRequestedNumberOfCharacters;
+
+  if(Controller::NO_OPERATION != (Controller::GET_LINE_BREAKS & operations))
+  {
+    // Retrieves the line break info. The line break info is used to split the text in 'paragraphs' to
+    // calculate the bidirectional info for each 'paragraph'.
+    // It's also used to layout the text (where it should be a new line) or to shape the text (text in different lines
+    // is not shaped together).
+    lineBreakInfo.Resize(numberOfCharacters, TextAbstraction::LINE_NO_BREAK);
+
+    SetLineBreakInfo(utf32Characters,
+                     startIndex,
+                     requestedNumberOfCharacters,
+                     lineBreakInfo);
+
+    if(impl.mModel->mLineWrapMode == ((Text::LineWrap::Mode)DevelText::LineWrap::HYPHENATION) ||
+        impl.mModel->mLineWrapMode == ((Text::LineWrap::Mode)DevelText::LineWrap::MIXED))
+    {
+      CharacterIndex end                 = startIndex + requestedNumberOfCharacters;
+      LineBreakInfo* lineBreakInfoBuffer = lineBreakInfo.Begin();
+
+      for(CharacterIndex index = startIndex; index < end; index++)
+      {
+        CharacterIndex wordEnd = index;
+        while((*(lineBreakInfoBuffer + wordEnd) != TextAbstraction::LINE_ALLOW_BREAK) && (*(lineBreakInfoBuffer + wordEnd) != TextAbstraction::LINE_MUST_BREAK))
+        {
+          wordEnd++;
+        }
+
+        if((wordEnd + 1) == end) // add last char
+        {
+          wordEnd++;
+        }
+
+        Vector<bool> hyphens = GetWordHyphens(utf32Characters.Begin() + index, wordEnd - index, nullptr);
+
+        for(CharacterIndex i = 0; i < (wordEnd - index); i++)
+        {
+          if(hyphens[i])
+          {
+            *(lineBreakInfoBuffer + index + i) = TextAbstraction::LINE_HYPHENATION_BREAK;
+          }
+        }
+
+        index = wordEnd;
+      }
+    }
+
+    // Create the paragraph info.
+    impl.mModel->mLogicalModel->CreateParagraphInfo(startIndex,
+                                                    requestedNumberOfCharacters);
+    updated = true;
+  }
+
+  const bool getScripts    = Controller::NO_OPERATION != (Controller::GET_SCRIPTS & operations);
+  const bool validateFonts = Controller::NO_OPERATION != (Controller::VALIDATE_FONTS & operations);
+
+  Vector<ScriptRun>& scripts    = impl.mModel->mLogicalModel->mScriptRuns;
+  Vector<FontRun>&   validFonts = impl.mModel->mLogicalModel->mFontRuns;
+
+  if(getScripts || validateFonts)
+  {
+    // Validates the fonts assigned by the application or assigns default ones.
+    // It makes sure all the characters are going to be rendered by the correct font.
+    MultilanguageSupport multilanguageSupport = MultilanguageSupport::Get();
+
+    if(getScripts)
+    {
+      // Retrieves the scripts used in the text.
+      multilanguageSupport.SetScripts(utf32Characters,
+                                      startIndex,
+                                      requestedNumberOfCharacters,
+                                      scripts);
+    }
+
+    if(validateFonts)
+    {
+      // Validate the fonts set through the mark-up string.
+      Vector<FontDescriptionRun>& fontDescriptionRuns = impl.mModel->mLogicalModel->mFontDescriptionRuns;
+
+      // Get the default font's description.
+      TextAbstraction::FontDescription defaultFontDescription;
+      TextAbstraction::PointSize26Dot6 defaultPointSize = TextAbstraction::FontClient::DEFAULT_POINT_SIZE * impl.mFontSizeScale;
+
+      //Get the number of points per one unit of point-size
+      uint32_t numberOfPointsPerOneUnitOfPointSize = impl.mFontClient.GetNumberOfPointsPerOneUnitOfPointSize();
+
+      if(impl.IsShowingPlaceholderText() && impl.mEventData && (nullptr != impl.mEventData->mPlaceholderFont))
+      {
+        // If the placeholder font is set specifically, only placeholder font is changed.
+        defaultFontDescription = impl.mEventData->mPlaceholderFont->mFontDescription;
+        if(impl.mEventData->mPlaceholderFont->sizeDefined)
+        {
+          defaultPointSize = impl.mEventData->mPlaceholderFont->mDefaultPointSize * impl.mFontSizeScale * numberOfPointsPerOneUnitOfPointSize;
+        }
+      }
+      else if(nullptr != impl.mFontDefaults)
+      {
+        // Set the normal font and the placeholder font.
+        defaultFontDescription = impl.mFontDefaults->mFontDescription;
+
+        if(impl.mTextFitEnabled)
+        {
+          defaultPointSize = impl.mFontDefaults->mFitPointSize * numberOfPointsPerOneUnitOfPointSize;
+        }
+        else
+        {
+          defaultPointSize = impl.mFontDefaults->mDefaultPointSize * impl.mFontSizeScale * numberOfPointsPerOneUnitOfPointSize;
+        }
+      }
+
+      // Validates the fonts. If there is a character with no assigned font it sets a default one.
+      // After this call, fonts are validated.
+      multilanguageSupport.ValidateFonts(utf32Characters,
+                                         scripts,
+                                         fontDescriptionRuns,
+                                         defaultFontDescription,
+                                         defaultPointSize,
+                                         startIndex,
+                                         requestedNumberOfCharacters,
+                                         validFonts);
+    }
+    updated = true;
+  }
+
+  Vector<Character> mirroredUtf32Characters;
+  bool              textMirrored       = false;
+  const Length      numberOfParagraphs = impl.mModel->mLogicalModel->mParagraphInfo.Count();
+  if(Controller::NO_OPERATION != (Controller::BIDI_INFO & operations))
+  {
+    Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo = impl.mModel->mLogicalModel->mBidirectionalParagraphInfo;
+    bidirectionalInfo.Reserve(numberOfParagraphs);
+
+    // Calculates the bidirectional info for the whole paragraph if it contains right to left scripts.
+    SetBidirectionalInfo(utf32Characters,
+                         scripts,
+                         lineBreakInfo,
+                         startIndex,
+                         requestedNumberOfCharacters,
+                         bidirectionalInfo,
+                         (impl.mModel->mMatchLayoutDirection != DevelText::MatchLayoutDirection::CONTENTS),
+                         impl.mLayoutDirection);
+
+    if(0u != bidirectionalInfo.Count())
+    {
+      // Only set the character directions if there is right to left characters.
+      Vector<CharacterDirection>& directions = impl.mModel->mLogicalModel->mCharacterDirections;
+      GetCharactersDirection(bidirectionalInfo,
+                             numberOfCharacters,
+                             startIndex,
+                             requestedNumberOfCharacters,
+                             directions);
+
+      // This paragraph has right to left text. Some characters may need to be mirrored.
+      // TODO: consider if the mirrored string can be stored as well.
+
+      textMirrored = GetMirroredText(utf32Characters,
+                                     directions,
+                                     bidirectionalInfo,
+                                     startIndex,
+                                     requestedNumberOfCharacters,
+                                     mirroredUtf32Characters);
+    }
+    else
+    {
+      // There is no right to left characters. Clear the directions vector.
+      impl.mModel->mLogicalModel->mCharacterDirections.Clear();
+    }
+    updated = true;
+  }
+
+  Vector<GlyphInfo>&      glyphs                = impl.mModel->mVisualModel->mGlyphs;
+  Vector<CharacterIndex>& glyphsToCharactersMap = impl.mModel->mVisualModel->mGlyphsToCharacters;
+  Vector<Length>&         charactersPerGlyph    = impl.mModel->mVisualModel->mCharactersPerGlyph;
+  Vector<GlyphIndex>      newParagraphGlyphs;
+  newParagraphGlyphs.Reserve(numberOfParagraphs);
+
+  const Length currentNumberOfGlyphs = glyphs.Count();
+  if(Controller::NO_OPERATION != (Controller::SHAPE_TEXT & operations))
+  {
+    const Vector<Character>& textToShape = textMirrored ? mirroredUtf32Characters : utf32Characters;
+    // Shapes the text.
+    ShapeText(textToShape,
+              lineBreakInfo,
+              scripts,
+              validFonts,
+              startIndex,
+              impl.mTextUpdateInfo.mStartGlyphIndex,
+              requestedNumberOfCharacters,
+              glyphs,
+              glyphsToCharactersMap,
+              charactersPerGlyph,
+              newParagraphGlyphs);
+
+    // Create the 'number of glyphs' per character and the glyph to character conversion tables.
+    impl.mModel->mVisualModel->CreateGlyphsPerCharacterTable(startIndex, impl.mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters);
+    impl.mModel->mVisualModel->CreateCharacterToGlyphTable(startIndex, impl.mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters);
+
+    updated = true;
+  }
+
+  const Length numberOfGlyphs = glyphs.Count() - currentNumberOfGlyphs;
+
+  if(Controller::NO_OPERATION != (Controller::GET_GLYPH_METRICS & operations))
+  {
+    GlyphInfo* glyphsBuffer = glyphs.Begin();
+    impl.mMetrics->GetGlyphMetrics(glyphsBuffer + impl.mTextUpdateInfo.mStartGlyphIndex, numberOfGlyphs);
+
+    // Update the width and advance of all new paragraph characters.
+    for(Vector<GlyphIndex>::ConstIterator it = newParagraphGlyphs.Begin(), endIt = newParagraphGlyphs.End(); it != endIt; ++it)
+    {
+      const GlyphIndex index = *it;
+      GlyphInfo&       glyph = *(glyphsBuffer + index);
+
+      glyph.xBearing = 0.f;
+      glyph.width    = 0.f;
+      glyph.advance  = 0.f;
+    }
+    updated = true;
+  }
+
+  if((nullptr != impl.mEventData) &&
+      impl.mEventData->mPreEditFlag &&
+     (0u != impl.mModel->mVisualModel->mCharactersToGlyph.Count()))
+  {
+    Dali::InputMethodContext::PreEditAttributeDataContainer attrs;
+    impl.mEventData->mInputMethodContext.GetPreeditStyle(attrs);
+    Dali::InputMethodContext::PreeditStyle type = Dali::InputMethodContext::PreeditStyle::NONE;
+
+    // Check the type of preedit and run it.
+    for(Dali::InputMethodContext::PreEditAttributeDataContainer::Iterator it = attrs.Begin(), endIt = attrs.End(); it != endIt; it++)
+    {
+      Dali::InputMethodContext::PreeditAttributeData attrData = *it;
+      DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::UpdateModel PreeditStyle type : %d  start %d end %d \n", attrData.preeditType, attrData.startIndex, attrData.endIndex);
+      type = attrData.preeditType;
+
+      // Check the number of commit characters for the start position.
+      unsigned int numberOfCommit  = impl.mEventData->mPrimaryCursorPosition - impl.mEventData->mPreEditLength;
+      Length       numberOfIndices = attrData.endIndex - attrData.startIndex;
+
+      switch(type)
+      {
+        case Dali::InputMethodContext::PreeditStyle::UNDERLINE:
+        {
+          // Add the underline for the pre-edit text.
+          GlyphRun underlineRun;
+          underlineRun.glyphIndex     = attrData.startIndex + numberOfCommit;
+          underlineRun.numberOfGlyphs = numberOfIndices;
+          impl.mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
+
+          //Mark-up processor case
+          if(impl.mModel->mVisualModel->IsMarkupProcessorEnabled())
+          {
+            impl.CopyUnderlinedFromLogicalToVisualModels(false);
+          }
+          break;
+        }
+        case Dali::InputMethodContext::PreeditStyle::REVERSE:
+        {
+          Vector4  textColor = impl.mModel->mVisualModel->GetTextColor();
+          ColorRun backgroundColorRun;
+          backgroundColorRun.characterRun.characterIndex     = attrData.startIndex + numberOfCommit;
+          backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
+          backgroundColorRun.color                           = textColor;
+          impl.mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun);
+
+          Vector4 backgroundColor = impl.mModel->mVisualModel->GetBackgroundColor();
+          if(backgroundColor.a == 0) // There is no text background color.
+          {
+            // Try use the control's background color.
+            if(nullptr != impl.mEditableControlInterface)
+            {
+              impl.mEditableControlInterface->GetControlBackgroundColor(backgroundColor);
+              if(backgroundColor.a == 0) // There is no control background color.
+              {
+                // Determines black or white color according to text color.
+                // Based on W3C Recommendations (https://www.w3.org/TR/WCAG20/)
+                float L         = CONSTANT_R * textColor.r + CONSTANT_G * textColor.g + CONSTANT_B * textColor.b;
+                backgroundColor = L > BRIGHTNESS_THRESHOLD ? BLACK : WHITE;
+              }
+            }
+          }
+
+          Vector<ColorRun> colorRuns;
+          colorRuns.Resize(1u);
+          ColorRun& colorRun                       = *(colorRuns.Begin());
+          colorRun.color                           = backgroundColor;
+          colorRun.characterRun.characterIndex     = attrData.startIndex + numberOfCommit;
+          colorRun.characterRun.numberOfCharacters = numberOfIndices;
+          impl.mModel->mLogicalModel->mColorRuns.PushBack(colorRun);
+
+          //Mark-up processor case
+          if(impl.mModel->mVisualModel->IsMarkupProcessorEnabled())
+          {
+            impl.CopyUnderlinedFromLogicalToVisualModels(false);
+          }
+          break;
+        }
+        case Dali::InputMethodContext::PreeditStyle::HIGHLIGHT:
+        {
+          ColorRun backgroundColorRun;
+          backgroundColorRun.characterRun.characterIndex     = attrData.startIndex + numberOfCommit;
+          backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
+          backgroundColorRun.color                           = LIGHT_BLUE;
+          impl.mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun);
+
+          //Mark-up processor case
+          if(impl.mModel->mVisualModel->IsMarkupProcessorEnabled())
+          {
+            impl.CopyUnderlinedFromLogicalToVisualModels(false);
+          }
+          break;
+        }
+        case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_1:
+        {
+          // CUSTOM_PLATFORM_STYLE_1 should be drawn with background and underline together.
+          ColorRun backgroundColorRun;
+          backgroundColorRun.characterRun.characterIndex     = attrData.startIndex + numberOfCommit;
+          backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
+          backgroundColorRun.color                           = BACKGROUND_SUB4;
+          impl.mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun);
+
+          GlyphRun underlineRun;
+          underlineRun.glyphIndex     = attrData.startIndex + numberOfCommit;
+          underlineRun.numberOfGlyphs = numberOfIndices;
+          impl.mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
+
+          //Mark-up processor case
+          if(impl.mModel->mVisualModel->IsMarkupProcessorEnabled())
+          {
+            impl.CopyUnderlinedFromLogicalToVisualModels(false);
+          }
+          break;
+        }
+        case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_2:
+        {
+          // CUSTOM_PLATFORM_STYLE_2 should be drawn with background and underline together.
+          ColorRun backgroundColorRun;
+          backgroundColorRun.characterRun.characterIndex     = attrData.startIndex + numberOfCommit;
+          backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
+          backgroundColorRun.color                           = BACKGROUND_SUB5;
+          impl.mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun);
+
+          GlyphRun underlineRun;
+          underlineRun.glyphIndex     = attrData.startIndex + numberOfCommit;
+          underlineRun.numberOfGlyphs = numberOfIndices;
+          impl.mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
+
+          //Mark-up processor case
+          if(impl.mModel->mVisualModel->IsMarkupProcessorEnabled())
+          {
+            impl.CopyUnderlinedFromLogicalToVisualModels(false);
+          }
+          break;
+        }
+        case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_3:
+        {
+          // CUSTOM_PLATFORM_STYLE_3 should be drawn with background and underline together.
+          ColorRun backgroundColorRun;
+          backgroundColorRun.characterRun.characterIndex     = attrData.startIndex + numberOfCommit;
+          backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
+          backgroundColorRun.color                           = BACKGROUND_SUB6;
+          impl.mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun);
+
+          GlyphRun underlineRun;
+          underlineRun.glyphIndex     = attrData.startIndex + numberOfCommit;
+          underlineRun.numberOfGlyphs = numberOfIndices;
+          impl.mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
+
+          //Mark-up processor case
+          if(impl.mModel->mVisualModel->IsMarkupProcessorEnabled())
+          {
+            impl.CopyUnderlinedFromLogicalToVisualModels(false);
+          }
+          break;
+        }
+        case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_4:
+        {
+          // CUSTOM_PLATFORM_STYLE_4 should be drawn with background and underline together.
+          ColorRun backgroundColorRun;
+          backgroundColorRun.characterRun.characterIndex     = attrData.startIndex + numberOfCommit;
+          backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
+          backgroundColorRun.color                           = BACKGROUND_SUB7;
+          impl.mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun);
+
+          GlyphRun underlineRun;
+          underlineRun.glyphIndex     = attrData.startIndex + numberOfCommit;
+          underlineRun.numberOfGlyphs = numberOfIndices;
+          impl.mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
+
+          //Mark-up processor case
+          if(impl.mModel->mVisualModel->IsMarkupProcessorEnabled())
+          {
+            impl.CopyUnderlinedFromLogicalToVisualModels(false);
+          }
+          break;
+        }
+        case Dali::InputMethodContext::PreeditStyle::NONE:
+        default:
+        {
+          break;
+        }
+      }
+    }
+    attrs.Clear();
+    updated = true;
+  }
+
+  if(Controller::NO_OPERATION != (Controller::COLOR & operations))
+  {
+    // Set the color runs in glyphs.
+    SetColorSegmentationInfo(impl.mModel->mLogicalModel->mColorRuns,
+                             impl.mModel->mVisualModel->mCharactersToGlyph,
+                             impl.mModel->mVisualModel->mGlyphsPerCharacter,
+                             startIndex,
+                             impl.mTextUpdateInfo.mStartGlyphIndex,
+                             requestedNumberOfCharacters,
+                             impl.mModel->mVisualModel->mColors,
+                             impl.mModel->mVisualModel->mColorIndices);
+
+    // Set the background color runs in glyphs.
+    SetColorSegmentationInfo(impl.mModel->mLogicalModel->mBackgroundColorRuns,
+                             impl.mModel->mVisualModel->mCharactersToGlyph,
+                             impl.mModel->mVisualModel->mGlyphsPerCharacter,
+                             startIndex,
+                             impl.mTextUpdateInfo.mStartGlyphIndex,
+                             requestedNumberOfCharacters,
+                             impl.mModel->mVisualModel->mBackgroundColors,
+                             impl.mModel->mVisualModel->mBackgroundColorIndices);
+
+    updated = true;
+  }
+
+  if((Controller::NO_OPERATION != (Controller::SHAPE_TEXT & operations)) &&
+     !((nullptr != impl.mEventData) &&
+         impl.mEventData->mPreEditFlag &&
+       (0u != impl.mModel->mVisualModel->mCharactersToGlyph.Count())))
+  {
+    //Mark-up processor case
+    if(impl.mModel->mVisualModel->IsMarkupProcessorEnabled())
+    {
+      impl.CopyUnderlinedFromLogicalToVisualModels(true);
+    }
+
+    updated = true;
+  }
+
+  // The estimated number of lines. Used to avoid reallocations when layouting.
+  impl.mTextUpdateInfo.mEstimatedNumberOfLines = std::max(impl.mModel->mVisualModel->mLines.Count(), impl.mModel->mLogicalModel->mParagraphInfo.Count());
+
+  // Set the previous number of characters for the next time the text is updated.
+  impl.mTextUpdateInfo.mPreviousNumberOfCharacters = numberOfCharacters;
+
+  return updated;
+}
+
+} // namespace Dali::Toolkit::Text
diff --git a/dali-toolkit/internal/text/text-controller-impl-model-updater.h b/dali-toolkit/internal/text/text-controller-impl-model-updater.h
new file mode 100644 (file)
index 0000000..2c5dd8c
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef DALI_TOOLKIT_TEXT_CONTROLLER_IMPL_MODEL_UPDATER_H
+#define DALI_TOOLKIT_TEXT_CONTROLLER_IMPL_MODEL_UPDATER_H
+
+/*
+ * Copyright (c) 2021 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-toolkit/internal/text/text-controller-impl.h>
+
+namespace Dali::Toolkit::Text
+{
+
+/**
+ * Contains methods for updating the models in the TextController
+ */
+struct ControllerImplModelUpdater
+{
+  using OperationsMask = Controller::OperationsMask;
+
+  /**
+   * @brief Updates the logical and visual models. Updates the style runs in the visual model when the text's styles changes.
+   *
+   * @param[in] impl A reference to the Controller::Impl class
+   * @param[in] operationsRequired The operations required
+   * @return true if mode has been modified.
+   */
+  static bool Update(Controller::Impl& impl, OperationsMask operationsRequired);
+};
+
+} // namespace Dali::Toolkit::Text
+
+#endif // DALI_TOOLKIT_TEXT_CONTROLLER_IMPL_MODEL_UPDATER_H
index 045fb8a..2edca46 100644 (file)
 // INTERNAL INCLUDES
 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
 #include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
-#include <dali-toolkit/internal/text/bidirectional-support.h>
 #include <dali-toolkit/internal/text/character-set-conversion.h>
-#include <dali-toolkit/internal/text/color-segmentation.h>
 #include <dali-toolkit/internal/text/cursor-helper-functions.h>
-#include <dali-toolkit/internal/text/hyphenator.h>
-#include <dali-toolkit/internal/text/multi-language-support.h>
-#include <dali-toolkit/internal/text/segmentation.h>
-#include <dali-toolkit/internal/text/shaper.h>
 #include <dali-toolkit/internal/text/text-control-interface.h>
 #include <dali-toolkit/internal/text/text-controller-impl-event-handler.h>
+#include <dali-toolkit/internal/text/text-controller-impl-model-updater.h>
 #include <dali-toolkit/internal/text/text-editable-control-interface.h>
 #include <dali-toolkit/internal/text/text-enumerations-impl.h>
 #include <dali-toolkit/internal/text/text-run-container.h>
@@ -60,28 +55,82 @@ struct BackgroundMesh
   Vector<unsigned short>   mIndices;  ///< container of indices
 };
 
-// The relative luminance of a color is defined as (L = 0.2126 * R + 0.7152 * G + 0.0722 * B)
-// based on W3C Recommendations (https://www.w3.org/TR/WCAG20/)
-const float         BRIGHTNESS_THRESHOLD = 0.179f;
-const float         CONSTANT_R           = 0.2126f;
-const float         CONSTANT_G           = 0.7152f;
-const float         CONSTANT_B           = 0.0722f;
-const Dali::Vector4 BLACK(0.f, 0.f, 0.f, 1.f);
-const Dali::Vector4 WHITE(1.f, 1.f, 1.f, 1.f);
-const Dali::Vector4 LIGHT_BLUE(0.75f, 0.96f, 1.f, 1.f);
-const Dali::Vector4 BACKGROUND_SUB4(0.58f, 0.87f, 0.96f, 1.f);
-const Dali::Vector4 BACKGROUND_SUB5(0.83f, 0.94f, 0.98f, 1.f);
-const Dali::Vector4 BACKGROUND_SUB6(1.f, 0.5f, 0.5f, 1.f);
-const Dali::Vector4 BACKGROUND_SUB7(1.f, 0.8f, 0.8f, 1.f);
-
 } // namespace
 
-namespace Dali
+namespace Dali::Toolkit::Text
 {
-namespace Toolkit
+
+namespace
 {
-namespace Text
+
+void SetDefaultInputStyle(InputStyle& inputStyle, const FontDefaults* const fontDefaults, const Vector4& textColor)
 {
+  // Sets the default text's color.
+  inputStyle.textColor      = textColor;
+  inputStyle.isDefaultColor = true;
+
+  inputStyle.familyName.clear();
+  inputStyle.weight = TextAbstraction::FontWeight::NORMAL;
+  inputStyle.width  = TextAbstraction::FontWidth::NORMAL;
+  inputStyle.slant  = TextAbstraction::FontSlant::NORMAL;
+  inputStyle.size   = 0.f;
+
+  inputStyle.lineSpacing = 0.f;
+
+  inputStyle.underlineProperties.clear();
+  inputStyle.shadowProperties.clear();
+  inputStyle.embossProperties.clear();
+  inputStyle.outlineProperties.clear();
+
+  inputStyle.isFamilyDefined = false;
+  inputStyle.isWeightDefined = false;
+  inputStyle.isWidthDefined  = false;
+  inputStyle.isSlantDefined  = false;
+  inputStyle.isSizeDefined   = false;
+
+  inputStyle.isLineSpacingDefined = false;
+
+  inputStyle.isUnderlineDefined = false;
+  inputStyle.isShadowDefined    = false;
+  inputStyle.isEmbossDefined    = false;
+  inputStyle.isOutlineDefined   = false;
+
+  // Sets the default font's family name, weight, width, slant and size.
+  if(fontDefaults)
+  {
+    if(fontDefaults->familyDefined)
+    {
+      inputStyle.familyName      = fontDefaults->mFontDescription.family;
+      inputStyle.isFamilyDefined = true;
+    }
+
+    if(fontDefaults->weightDefined)
+    {
+      inputStyle.weight          = fontDefaults->mFontDescription.weight;
+      inputStyle.isWeightDefined = true;
+    }
+
+    if(fontDefaults->widthDefined)
+    {
+      inputStyle.width          = fontDefaults->mFontDescription.width;
+      inputStyle.isWidthDefined = true;
+    }
+
+    if(fontDefaults->slantDefined)
+    {
+      inputStyle.slant          = fontDefaults->mFontDescription.slant;
+      inputStyle.isSlantDefined = true;
+    }
+
+    if(fontDefaults->sizeDefined)
+    {
+      inputStyle.size          = fontDefaults->mDefaultPointSize;
+      inputStyle.isSizeDefined = true;
+    }
+  }
+}
+} // unnamed Namespace
+
 EventData::EventData(DecoratorPtr decorator, InputMethodContext& inputMethodContext)
 : mDecorator(decorator),
   mInputMethodContext(inputMethodContext),
@@ -588,600 +637,12 @@ void Controller::Impl::ClearModelData(CharacterIndex startIndex, CharacterIndex
 
 bool Controller::Impl::UpdateModel(OperationsMask operationsRequired)
 {
-  DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::UpdateModel\n");
-
-  // Calculate the operations to be done.
-  const OperationsMask operations = static_cast<OperationsMask>(mOperationsPending & operationsRequired);
-
-  if(NO_OPERATION == operations)
-  {
-    // Nothing to do if no operations are pending and required.
-    return false;
-  }
-
-  Vector<Character>& srcCharacters = mModel->mLogicalModel->mText;
-  Vector<Character>  displayCharacters;
-  bool               useHiddenText = false;
-  if(mHiddenInput && mEventData != nullptr && !mEventData->mIsShowingPlaceholderText)
-  {
-    mHiddenInput->Substitute(srcCharacters, displayCharacters);
-    useHiddenText = true;
-  }
-
-  Vector<Character>& utf32Characters    = useHiddenText ? displayCharacters : srcCharacters;
-  const Length       numberOfCharacters = utf32Characters.Count();
-
-  // Index to the first character of the first paragraph to be updated.
-  CharacterIndex startIndex = 0u;
-  // Number of characters of the paragraphs to be removed.
-  Length paragraphCharacters = 0u;
-
-  CalculateTextUpdateIndices(paragraphCharacters);
-
-  // Check whether the indices for updating the text is valid
-  if(numberOfCharacters > 0u &&
-     (mTextUpdateInfo.mParagraphCharacterIndex > numberOfCharacters ||
-      mTextUpdateInfo.mRequestedNumberOfCharacters > numberOfCharacters))
-  {
-    std::string currentText;
-    Utf32ToUtf8(mModel->mLogicalModel->mText.Begin(), numberOfCharacters, currentText);
-
-    DALI_LOG_ERROR("Controller::Impl::UpdateModel: mTextUpdateInfo has invalid indices\n");
-    DALI_LOG_ERROR("Number of characters: %d, current text is: %s\n", numberOfCharacters, currentText.c_str());
-
-    // Dump mTextUpdateInfo
-    DALI_LOG_ERROR("Dump mTextUpdateInfo:\n");
-    DALI_LOG_ERROR("     mTextUpdateInfo.mCharacterIndex = %u\n", mTextUpdateInfo.mCharacterIndex);
-    DALI_LOG_ERROR("     mTextUpdateInfo.mNumberOfCharactersToRemove = %u\n", mTextUpdateInfo.mNumberOfCharactersToRemove);
-    DALI_LOG_ERROR("     mTextUpdateInfo.mNumberOfCharactersToAdd = %u\n", mTextUpdateInfo.mNumberOfCharactersToAdd);
-    DALI_LOG_ERROR("     mTextUpdateInfo.mPreviousNumberOfCharacters = %u\n", mTextUpdateInfo.mPreviousNumberOfCharacters);
-    DALI_LOG_ERROR("     mTextUpdateInfo.mParagraphCharacterIndex = %u\n", mTextUpdateInfo.mParagraphCharacterIndex);
-    DALI_LOG_ERROR("     mTextUpdateInfo.mRequestedNumberOfCharacters = %u\n", mTextUpdateInfo.mRequestedNumberOfCharacters);
-    DALI_LOG_ERROR("     mTextUpdateInfo.mStartGlyphIndex = %u\n", mTextUpdateInfo.mStartGlyphIndex);
-    DALI_LOG_ERROR("     mTextUpdateInfo.mStartLineIndex = %u\n", mTextUpdateInfo.mStartLineIndex);
-    DALI_LOG_ERROR("     mTextUpdateInfo.mEstimatedNumberOfLines = %u\n", mTextUpdateInfo.mEstimatedNumberOfLines);
-    DALI_LOG_ERROR("     mTextUpdateInfo.mClearAll = %d\n", mTextUpdateInfo.mClearAll);
-    DALI_LOG_ERROR("     mTextUpdateInfo.mFullRelayoutNeeded = %d\n", mTextUpdateInfo.mFullRelayoutNeeded);
-    DALI_LOG_ERROR("     mTextUpdateInfo.mIsLastCharacterNewParagraph = %d\n", mTextUpdateInfo.mIsLastCharacterNewParagraph);
-
-    return false;
-  }
-
-  startIndex = mTextUpdateInfo.mParagraphCharacterIndex;
-
-  if(mTextUpdateInfo.mClearAll ||
-     (0u != paragraphCharacters))
-  {
-    ClearModelData(startIndex, startIndex + ((paragraphCharacters > 0u) ? paragraphCharacters - 1u : 0u), operations);
-  }
-
-  mTextUpdateInfo.mClearAll = false;
-
-  // Whether the model is updated.
-  bool updated = false;
-
-  Vector<LineBreakInfo>& lineBreakInfo               = mModel->mLogicalModel->mLineBreakInfo;
-  const Length           requestedNumberOfCharacters = mTextUpdateInfo.mRequestedNumberOfCharacters;
-
-  if(NO_OPERATION != (GET_LINE_BREAKS & operations))
-  {
-    // Retrieves the line break info. The line break info is used to split the text in 'paragraphs' to
-    // calculate the bidirectional info for each 'paragraph'.
-    // It's also used to layout the text (where it should be a new line) or to shape the text (text in different lines
-    // is not shaped together).
-    lineBreakInfo.Resize(numberOfCharacters, TextAbstraction::LINE_NO_BREAK);
-
-    SetLineBreakInfo(utf32Characters,
-                     startIndex,
-                     requestedNumberOfCharacters,
-                     lineBreakInfo);
-
-    if(mModel->mLineWrapMode == ((Text::LineWrap::Mode)DevelText::LineWrap::HYPHENATION) ||
-       mModel->mLineWrapMode == ((Text::LineWrap::Mode)DevelText::LineWrap::MIXED))
-    {
-      CharacterIndex end                 = startIndex + requestedNumberOfCharacters;
-      LineBreakInfo* lineBreakInfoBuffer = lineBreakInfo.Begin();
-
-      for(CharacterIndex index = startIndex; index < end; index++)
-      {
-        CharacterIndex wordEnd = index;
-        while((*(lineBreakInfoBuffer + wordEnd) != TextAbstraction::LINE_ALLOW_BREAK) && (*(lineBreakInfoBuffer + wordEnd) != TextAbstraction::LINE_MUST_BREAK))
-        {
-          wordEnd++;
-        }
-
-        if((wordEnd + 1) == end) // add last char
-        {
-          wordEnd++;
-        }
-
-        Vector<bool> hyphens = GetWordHyphens(utf32Characters.Begin() + index, wordEnd - index, nullptr);
-
-        for(CharacterIndex i = 0; i < (wordEnd - index); i++)
-        {
-          if(hyphens[i])
-          {
-            *(lineBreakInfoBuffer + index + i) = TextAbstraction::LINE_HYPHENATION_BREAK;
-          }
-        }
-
-        index = wordEnd;
-      }
-    }
-
-    // Create the paragraph info.
-    mModel->mLogicalModel->CreateParagraphInfo(startIndex,
-                                               requestedNumberOfCharacters);
-    updated = true;
-  }
-
-  const bool getScripts    = NO_OPERATION != (GET_SCRIPTS & operations);
-  const bool validateFonts = NO_OPERATION != (VALIDATE_FONTS & operations);
-
-  Vector<ScriptRun>& scripts    = mModel->mLogicalModel->mScriptRuns;
-  Vector<FontRun>&   validFonts = mModel->mLogicalModel->mFontRuns;
-
-  if(getScripts || validateFonts)
-  {
-    // Validates the fonts assigned by the application or assigns default ones.
-    // It makes sure all the characters are going to be rendered by the correct font.
-    MultilanguageSupport multilanguageSupport = MultilanguageSupport::Get();
-
-    if(getScripts)
-    {
-      // Retrieves the scripts used in the text.
-      multilanguageSupport.SetScripts(utf32Characters,
-                                      startIndex,
-                                      requestedNumberOfCharacters,
-                                      scripts);
-    }
-
-    if(validateFonts)
-    {
-      // Validate the fonts set through the mark-up string.
-      Vector<FontDescriptionRun>& fontDescriptionRuns = mModel->mLogicalModel->mFontDescriptionRuns;
-
-      // Get the default font's description.
-      TextAbstraction::FontDescription defaultFontDescription;
-      TextAbstraction::PointSize26Dot6 defaultPointSize = TextAbstraction::FontClient::DEFAULT_POINT_SIZE * mFontSizeScale;
-
-      //Get the number of points per one unit of point-size
-      uint32_t numberOfPointsPerOneUnitOfPointSize = mFontClient.GetNumberOfPointsPerOneUnitOfPointSize();
-
-      if(IsShowingPlaceholderText() && mEventData && (nullptr != mEventData->mPlaceholderFont))
-      {
-        // If the placeholder font is set specifically, only placeholder font is changed.
-        defaultFontDescription = mEventData->mPlaceholderFont->mFontDescription;
-        if(mEventData->mPlaceholderFont->sizeDefined)
-        {
-          defaultPointSize = mEventData->mPlaceholderFont->mDefaultPointSize * mFontSizeScale * numberOfPointsPerOneUnitOfPointSize;
-        }
-      }
-      else if(nullptr != mFontDefaults)
-      {
-        // Set the normal font and the placeholder font.
-        defaultFontDescription = mFontDefaults->mFontDescription;
-
-        if(mTextFitEnabled)
-        {
-          defaultPointSize = mFontDefaults->mFitPointSize * numberOfPointsPerOneUnitOfPointSize;
-        }
-        else
-        {
-          defaultPointSize = mFontDefaults->mDefaultPointSize * mFontSizeScale * numberOfPointsPerOneUnitOfPointSize;
-        }
-      }
-
-      // Validates the fonts. If there is a character with no assigned font it sets a default one.
-      // After this call, fonts are validated.
-      multilanguageSupport.ValidateFonts(utf32Characters,
-                                         scripts,
-                                         fontDescriptionRuns,
-                                         defaultFontDescription,
-                                         defaultPointSize,
-                                         startIndex,
-                                         requestedNumberOfCharacters,
-                                         validFonts);
-    }
-    updated = true;
-  }
-
-  Vector<Character> mirroredUtf32Characters;
-  bool              textMirrored       = false;
-  const Length      numberOfParagraphs = mModel->mLogicalModel->mParagraphInfo.Count();
-  if(NO_OPERATION != (BIDI_INFO & operations))
-  {
-    Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo = mModel->mLogicalModel->mBidirectionalParagraphInfo;
-    bidirectionalInfo.Reserve(numberOfParagraphs);
-
-    // Calculates the bidirectional info for the whole paragraph if it contains right to left scripts.
-    SetBidirectionalInfo(utf32Characters,
-                         scripts,
-                         lineBreakInfo,
-                         startIndex,
-                         requestedNumberOfCharacters,
-                         bidirectionalInfo,
-                         (mModel->mMatchLayoutDirection != DevelText::MatchLayoutDirection::CONTENTS),
-                         mLayoutDirection);
-
-    if(0u != bidirectionalInfo.Count())
-    {
-      // Only set the character directions if there is right to left characters.
-      Vector<CharacterDirection>& directions = mModel->mLogicalModel->mCharacterDirections;
-      GetCharactersDirection(bidirectionalInfo,
-                             numberOfCharacters,
-                             startIndex,
-                             requestedNumberOfCharacters,
-                             directions);
-
-      // This paragraph has right to left text. Some characters may need to be mirrored.
-      // TODO: consider if the mirrored string can be stored as well.
-
-      textMirrored = GetMirroredText(utf32Characters,
-                                     directions,
-                                     bidirectionalInfo,
-                                     startIndex,
-                                     requestedNumberOfCharacters,
-                                     mirroredUtf32Characters);
-    }
-    else
-    {
-      // There is no right to left characters. Clear the directions vector.
-      mModel->mLogicalModel->mCharacterDirections.Clear();
-    }
-    updated = true;
-  }
-
-  Vector<GlyphInfo>&      glyphs                = mModel->mVisualModel->mGlyphs;
-  Vector<CharacterIndex>& glyphsToCharactersMap = mModel->mVisualModel->mGlyphsToCharacters;
-  Vector<Length>&         charactersPerGlyph    = mModel->mVisualModel->mCharactersPerGlyph;
-  Vector<GlyphIndex>      newParagraphGlyphs;
-  newParagraphGlyphs.Reserve(numberOfParagraphs);
-
-  const Length currentNumberOfGlyphs = glyphs.Count();
-  if(NO_OPERATION != (SHAPE_TEXT & operations))
-  {
-    const Vector<Character>& textToShape = textMirrored ? mirroredUtf32Characters : utf32Characters;
-    // Shapes the text.
-    ShapeText(textToShape,
-              lineBreakInfo,
-              scripts,
-              validFonts,
-              startIndex,
-              mTextUpdateInfo.mStartGlyphIndex,
-              requestedNumberOfCharacters,
-              glyphs,
-              glyphsToCharactersMap,
-              charactersPerGlyph,
-              newParagraphGlyphs);
-
-    // Create the 'number of glyphs' per character and the glyph to character conversion tables.
-    mModel->mVisualModel->CreateGlyphsPerCharacterTable(startIndex, mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters);
-    mModel->mVisualModel->CreateCharacterToGlyphTable(startIndex, mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters);
-
-    updated = true;
-  }
-
-  const Length numberOfGlyphs = glyphs.Count() - currentNumberOfGlyphs;
-
-  if(NO_OPERATION != (GET_GLYPH_METRICS & operations))
-  {
-    GlyphInfo* glyphsBuffer = glyphs.Begin();
-    mMetrics->GetGlyphMetrics(glyphsBuffer + mTextUpdateInfo.mStartGlyphIndex, numberOfGlyphs);
-
-    // Update the width and advance of all new paragraph characters.
-    for(Vector<GlyphIndex>::ConstIterator it = newParagraphGlyphs.Begin(), endIt = newParagraphGlyphs.End(); it != endIt; ++it)
-    {
-      const GlyphIndex index = *it;
-      GlyphInfo&       glyph = *(glyphsBuffer + index);
-
-      glyph.xBearing = 0.f;
-      glyph.width    = 0.f;
-      glyph.advance  = 0.f;
-    }
-    updated = true;
-  }
-
-  if((nullptr != mEventData) &&
-     mEventData->mPreEditFlag &&
-     (0u != mModel->mVisualModel->mCharactersToGlyph.Count()))
-  {
-    Dali::InputMethodContext::PreEditAttributeDataContainer attrs;
-    mEventData->mInputMethodContext.GetPreeditStyle(attrs);
-    Dali::InputMethodContext::PreeditStyle type = Dali::InputMethodContext::PreeditStyle::NONE;
-
-    // Check the type of preedit and run it.
-    for(Dali::InputMethodContext::PreEditAttributeDataContainer::Iterator it = attrs.Begin(), endIt = attrs.End(); it != endIt; it++)
-    {
-      Dali::InputMethodContext::PreeditAttributeData attrData = *it;
-      DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::UpdateModel PreeditStyle type : %d  start %d end %d \n", attrData.preeditType, attrData.startIndex, attrData.endIndex);
-      type = attrData.preeditType;
-
-      // Check the number of commit characters for the start position.
-      unsigned int numberOfCommit  = mEventData->mPrimaryCursorPosition - mEventData->mPreEditLength;
-      Length       numberOfIndices = attrData.endIndex - attrData.startIndex;
-
-      switch(type)
-      {
-        case Dali::InputMethodContext::PreeditStyle::UNDERLINE:
-        {
-          // Add the underline for the pre-edit text.
-          GlyphRun underlineRun;
-          underlineRun.glyphIndex     = attrData.startIndex + numberOfCommit;
-          underlineRun.numberOfGlyphs = numberOfIndices;
-          mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
-
-          //Mark-up processor case
-          if(mModel->mVisualModel->IsMarkupProcessorEnabled())
-          {
-            CopyUnderlinedFromLogicalToVisualModels(false);
-          }
-          break;
-        }
-        case Dali::InputMethodContext::PreeditStyle::REVERSE:
-        {
-          Vector4  textColor = mModel->mVisualModel->GetTextColor();
-          ColorRun backgroundColorRun;
-          backgroundColorRun.characterRun.characterIndex     = attrData.startIndex + numberOfCommit;
-          backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
-          backgroundColorRun.color                           = textColor;
-          mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun);
-
-          Vector4 backgroundColor = mModel->mVisualModel->GetBackgroundColor();
-          if(backgroundColor.a == 0) // There is no text background color.
-          {
-            // Try use the control's background color.
-            if(nullptr != mEditableControlInterface)
-            {
-              mEditableControlInterface->GetControlBackgroundColor(backgroundColor);
-              if(backgroundColor.a == 0) // There is no control background color.
-              {
-                // Determines black or white color according to text color.
-                // Based on W3C Recommendations (https://www.w3.org/TR/WCAG20/)
-                float L         = CONSTANT_R * textColor.r + CONSTANT_G * textColor.g + CONSTANT_B * textColor.b;
-                backgroundColor = L > BRIGHTNESS_THRESHOLD ? BLACK : WHITE;
-              }
-            }
-          }
-
-          Vector<ColorRun> colorRuns;
-          colorRuns.Resize(1u);
-          ColorRun& colorRun                       = *(colorRuns.Begin());
-          colorRun.color                           = backgroundColor;
-          colorRun.characterRun.characterIndex     = attrData.startIndex + numberOfCommit;
-          colorRun.characterRun.numberOfCharacters = numberOfIndices;
-          mModel->mLogicalModel->mColorRuns.PushBack(colorRun);
-
-          //Mark-up processor case
-          if(mModel->mVisualModel->IsMarkupProcessorEnabled())
-          {
-            CopyUnderlinedFromLogicalToVisualModels(false);
-          }
-          break;
-        }
-        case Dali::InputMethodContext::PreeditStyle::HIGHLIGHT:
-        {
-          ColorRun backgroundColorRun;
-          backgroundColorRun.characterRun.characterIndex     = attrData.startIndex + numberOfCommit;
-          backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
-          backgroundColorRun.color                           = LIGHT_BLUE;
-          mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun);
-
-          //Mark-up processor case
-          if(mModel->mVisualModel->IsMarkupProcessorEnabled())
-          {
-            CopyUnderlinedFromLogicalToVisualModels(false);
-          }
-          break;
-        }
-        case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_1:
-        {
-          // CUSTOM_PLATFORM_STYLE_1 should be drawn with background and underline together.
-          ColorRun backgroundColorRun;
-          backgroundColorRun.characterRun.characterIndex     = attrData.startIndex + numberOfCommit;
-          backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
-          backgroundColorRun.color                           = BACKGROUND_SUB4;
-          mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun);
-
-          GlyphRun underlineRun;
-          underlineRun.glyphIndex     = attrData.startIndex + numberOfCommit;
-          underlineRun.numberOfGlyphs = numberOfIndices;
-          mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
-
-          //Mark-up processor case
-          if(mModel->mVisualModel->IsMarkupProcessorEnabled())
-          {
-            CopyUnderlinedFromLogicalToVisualModels(false);
-          }
-          break;
-        }
-        case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_2:
-        {
-          // CUSTOM_PLATFORM_STYLE_2 should be drawn with background and underline together.
-          ColorRun backgroundColorRun;
-          backgroundColorRun.characterRun.characterIndex     = attrData.startIndex + numberOfCommit;
-          backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
-          backgroundColorRun.color                           = BACKGROUND_SUB5;
-          mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun);
-
-          GlyphRun underlineRun;
-          underlineRun.glyphIndex     = attrData.startIndex + numberOfCommit;
-          underlineRun.numberOfGlyphs = numberOfIndices;
-          mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
-
-          //Mark-up processor case
-          if(mModel->mVisualModel->IsMarkupProcessorEnabled())
-          {
-            CopyUnderlinedFromLogicalToVisualModels(false);
-          }
-          break;
-        }
-        case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_3:
-        {
-          // CUSTOM_PLATFORM_STYLE_3 should be drawn with background and underline together.
-          ColorRun backgroundColorRun;
-          backgroundColorRun.characterRun.characterIndex     = attrData.startIndex + numberOfCommit;
-          backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
-          backgroundColorRun.color                           = BACKGROUND_SUB6;
-          mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun);
-
-          GlyphRun underlineRun;
-          underlineRun.glyphIndex     = attrData.startIndex + numberOfCommit;
-          underlineRun.numberOfGlyphs = numberOfIndices;
-          mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
-
-          //Mark-up processor case
-          if(mModel->mVisualModel->IsMarkupProcessorEnabled())
-          {
-            CopyUnderlinedFromLogicalToVisualModels(false);
-          }
-          break;
-        }
-        case Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_4:
-        {
-          // CUSTOM_PLATFORM_STYLE_4 should be drawn with background and underline together.
-          ColorRun backgroundColorRun;
-          backgroundColorRun.characterRun.characterIndex     = attrData.startIndex + numberOfCommit;
-          backgroundColorRun.characterRun.numberOfCharacters = numberOfIndices;
-          backgroundColorRun.color                           = BACKGROUND_SUB7;
-          mModel->mLogicalModel->mBackgroundColorRuns.PushBack(backgroundColorRun);
-
-          GlyphRun underlineRun;
-          underlineRun.glyphIndex     = attrData.startIndex + numberOfCommit;
-          underlineRun.numberOfGlyphs = numberOfIndices;
-          mModel->mVisualModel->mUnderlineRuns.PushBack(underlineRun);
-
-          //Mark-up processor case
-          if(mModel->mVisualModel->IsMarkupProcessorEnabled())
-          {
-            CopyUnderlinedFromLogicalToVisualModels(false);
-          }
-          break;
-        }
-        case Dali::InputMethodContext::PreeditStyle::NONE:
-        default:
-        {
-          break;
-        }
-      }
-    }
-    attrs.Clear();
-    updated = true;
-  }
-
-  if(NO_OPERATION != (COLOR & operations))
-  {
-    // Set the color runs in glyphs.
-    SetColorSegmentationInfo(mModel->mLogicalModel->mColorRuns,
-                             mModel->mVisualModel->mCharactersToGlyph,
-                             mModel->mVisualModel->mGlyphsPerCharacter,
-                             startIndex,
-                             mTextUpdateInfo.mStartGlyphIndex,
-                             requestedNumberOfCharacters,
-                             mModel->mVisualModel->mColors,
-                             mModel->mVisualModel->mColorIndices);
-
-    // Set the background color runs in glyphs.
-    SetColorSegmentationInfo(mModel->mLogicalModel->mBackgroundColorRuns,
-                             mModel->mVisualModel->mCharactersToGlyph,
-                             mModel->mVisualModel->mGlyphsPerCharacter,
-                             startIndex,
-                             mTextUpdateInfo.mStartGlyphIndex,
-                             requestedNumberOfCharacters,
-                             mModel->mVisualModel->mBackgroundColors,
-                             mModel->mVisualModel->mBackgroundColorIndices);
-
-    updated = true;
-  }
-
-  if((NO_OPERATION != (SHAPE_TEXT & operations)) &&
-     !((nullptr != mEventData) &&
-       mEventData->mPreEditFlag &&
-       (0u != mModel->mVisualModel->mCharactersToGlyph.Count())))
-  {
-    //Mark-up processor case
-    if(mModel->mVisualModel->IsMarkupProcessorEnabled())
-    {
-      CopyUnderlinedFromLogicalToVisualModels(true);
-    }
-
-    updated = true;
-  }
-
-  // The estimated number of lines. Used to avoid reallocations when layouting.
-  mTextUpdateInfo.mEstimatedNumberOfLines = std::max(mModel->mVisualModel->mLines.Count(), mModel->mLogicalModel->mParagraphInfo.Count());
-
-  // Set the previous number of characters for the next time the text is updated.
-  mTextUpdateInfo.mPreviousNumberOfCharacters = numberOfCharacters;
-
-  return updated;
+  return ControllerImplModelUpdater::Update(*this, operationsRequired);
 }
 
 void Controller::Impl::RetrieveDefaultInputStyle(InputStyle& inputStyle)
 {
-  // Sets the default text's color.
-  inputStyle.textColor      = mTextColor;
-  inputStyle.isDefaultColor = true;
-
-  inputStyle.familyName.clear();
-  inputStyle.weight = TextAbstraction::FontWeight::NORMAL;
-  inputStyle.width  = TextAbstraction::FontWidth::NORMAL;
-  inputStyle.slant  = TextAbstraction::FontSlant::NORMAL;
-  inputStyle.size   = 0.f;
-
-  inputStyle.lineSpacing = 0.f;
-
-  inputStyle.underlineProperties.clear();
-  inputStyle.shadowProperties.clear();
-  inputStyle.embossProperties.clear();
-  inputStyle.outlineProperties.clear();
-
-  inputStyle.isFamilyDefined = false;
-  inputStyle.isWeightDefined = false;
-  inputStyle.isWidthDefined  = false;
-  inputStyle.isSlantDefined  = false;
-  inputStyle.isSizeDefined   = false;
-
-  inputStyle.isLineSpacingDefined = false;
-
-  inputStyle.isUnderlineDefined = false;
-  inputStyle.isShadowDefined    = false;
-  inputStyle.isEmbossDefined    = false;
-  inputStyle.isOutlineDefined   = false;
-
-  // Sets the default font's family name, weight, width, slant and size.
-  if(mFontDefaults)
-  {
-    if(mFontDefaults->familyDefined)
-    {
-      inputStyle.familyName      = mFontDefaults->mFontDescription.family;
-      inputStyle.isFamilyDefined = true;
-    }
-
-    if(mFontDefaults->weightDefined)
-    {
-      inputStyle.weight          = mFontDefaults->mFontDescription.weight;
-      inputStyle.isWeightDefined = true;
-    }
-
-    if(mFontDefaults->widthDefined)
-    {
-      inputStyle.width          = mFontDefaults->mFontDescription.width;
-      inputStyle.isWidthDefined = true;
-    }
-
-    if(mFontDefaults->slantDefined)
-    {
-      inputStyle.slant          = mFontDefaults->mFontDescription.slant;
-      inputStyle.isSlantDefined = true;
-    }
-
-    if(mFontDefaults->sizeDefined)
-    {
-      inputStyle.size          = mFontDefaults->mDefaultPointSize;
-      inputStyle.isSizeDefined = true;
-    }
-  }
+  SetDefaultInputStyle(inputStyle, mFontDefaults, mTextColor);
 }
 
 float Controller::Impl::GetDefaultFontLineHeight()
@@ -2125,7 +1586,7 @@ Actor Controller::Impl::CreateBackgroundActor()
 
     const Vector2 textSize = mView.GetLayoutSize();
 
-    const float offsetX = textSize.width * 0.5f;
+    const float offsetX = alignmentOffset + textSize.width * 0.5f;
     const float offsetY = textSize.height * 0.5f;
 
     const Vector4* const    backgroundColorsBuffer       = mView.GetBackgroundColors();
@@ -2297,8 +1758,4 @@ void Controller::Impl::CopyUnderlinedFromLogicalToVisualModels(bool shouldClearP
   }
 }
 
-} // namespace Text
-
-} // namespace Toolkit
-
-} // namespace Dali
+} // namespace Dali::Toolkit::Text
index 02fbff8..0c6297f 100644 (file)
@@ -46,6 +46,7 @@ const float DEFAULT_FONT_SIZE_SCALE = 1.f;
 struct CursorInfo;
 struct FontDefaults;
 struct ControllerImplEventHandler;
+struct ControllerImplModelUpdater;
 struct SelectionHandleController;
 
 class SelectableControlInterface;
@@ -845,6 +846,7 @@ public:
 
 private:
   friend ControllerImplEventHandler;
+  friend ControllerImplModelUpdater;
   friend SelectionHandleController;
 };
 
index f8aed47..5ee926e 100644 (file)
@@ -208,22 +208,18 @@ void TransitionBase::SetAnimation()
     return;
   }
 
-  // If this transition is not a transition from a Control to another Control
-  // and a transition effect to appear with delay,
-  // the mTarget should not be shown until delay seconds.
-  if(!IsPairTransition() && mIsAppearingTransition && mAnimation && mTimePeriod.delaySeconds > Dali::Math::MACHINE_EPSILON_10)
-  {
-    Dali::KeyFrames initialKeyframes = Dali::KeyFrames::New();
-    initialKeyframes.Add(0.0f, OPACITY_TRANSPARENT);
-    initialKeyframes.Add(1.0f, OPACITY_TRANSPARENT);
-    mAnimation.AnimateBetween(Property(mTarget, Dali::Actor::Property::OPACITY), initialKeyframes, TimePeriod(mTimePeriod.delaySeconds));
-  }
-
   for(uint32_t i = 0; i < mStartPropertyMap.Count(); ++i)
   {
     Property::Value* finishValue = mFinishPropertyMap.Find(mStartPropertyMap.GetKeyAt(i).indexKey);
     if(finishValue)
     {
+      // If this transition is appearing transition, this property keeps start value during delay.
+      // If multiple transitions are applied to this Control and others run before this transition,
+      // this property should keep start value until this transition starts.
+      if(!IsPairTransition() && IsAppearingTransition() && mTimePeriod.delaySeconds > Dali::Math::MACHINE_EPSILON_10)
+      {
+        mTarget.SetProperty(mStartPropertyMap.GetKeyAt(i).indexKey, mStartPropertyMap.GetValue(i));
+      }
       AnimateBetween(mTarget, mStartPropertyMap.GetKeyAt(i).indexKey, mStartPropertyMap.GetValue(i), *finishValue);
     }
   }
index 409eb60..b194e52 100644 (file)
@@ -101,6 +101,30 @@ public:
     mIsAppearingTransition = appearingTransition;
   }
 
+  /**
+   * @brief Returns whether this transition is appearing transition or not
+   */
+  bool IsAppearingTransition() const
+  {
+    return mIsAppearingTransition;
+  }
+
+  /**
+   * @brief Returns whether this transition is a transition from a Control to another Control or effect to appearing or disappearing.
+   */
+  bool IsPairTransition() const
+  {
+    return mIsPairTransition;
+  }
+
+  /**
+   * @brief Returns target which will be transition.
+   */
+  const Dali::Toolkit::Control GetTarget() const
+  {
+    return mTarget;
+  }
+
 protected:
 
   /**
@@ -159,14 +183,6 @@ protected:
   }
 
   /**
-   * @brief Returns whether this transition is appearing transition or not
-   */
-  bool IsAppearingTransition() const
-  {
-    return mIsAppearingTransition;
-  }
-
-  /**
    * @brief Set whether this transition is a transition from a Control to another Control or effect to appearing or disappearing.
    * @param[in] pairTransition True if this transition is appearing transition.
    */
@@ -175,14 +191,6 @@ protected:
     mIsPairTransition = pairTransition;
   }
 
-  /**
-   * @brief Returns whether this transition is a transition from a Control to another Control or effect to appearing or disappearing.
-   */
-  bool IsPairTransition() const
-  {
-    return mIsPairTransition;
-  }
-
 protected:
   /**
    * Construct a new TransitionBase.
index fd019b6..d1b16af 100644 (file)
@@ -37,6 +37,13 @@ namespace
 // Signals
 static constexpr std::string_view SIGNAL_FINISHED = "finished";
 
+static constexpr float OPACITY_TRANSPARENT = 0.0f;
+
+float CustomAlphaFunction(float progress)
+{
+  return (progress >= 1.0f) ? 1.0f : 0.0f;
+}
+
 BaseHandle Create()
 {
   return Dali::Toolkit::TransitionSet::New();
@@ -117,9 +124,46 @@ void TransitionSet::TransitionPreProcess()
 
 void TransitionSet::TransitionStart()
 {
+  std::vector<std::pair<Dali::Actor, float>> minimumDelays;
   for(auto&& transition : mTransitions)
   {
     transition->Play();
+
+    // If target Control has appearing transition, the target will not be rendered during delay.
+    // And if the Control has multiple transitions, the target will not be rendered during minimum delay of the transitions.
+    // Here we can find minimum delay of each target.
+    if(!transition->IsPairTransition() && transition->IsAppearingTransition())
+    {
+      bool found = false;
+      for(uint32_t index = 0; index < minimumDelays.size(); ++index)
+      {
+        if(minimumDelays[index].first == transition->GetTarget())
+        {
+          minimumDelays[index].second = std::min(minimumDelays[index].second, transition->GetTimePeriod().delaySeconds);
+          found = true;
+          break;
+        }
+      }
+      if(!found)
+      {
+        minimumDelays.push_back(std::pair<Dali::Actor, float>(transition->GetTarget(), transition->GetTimePeriod().delaySeconds));
+      }
+    }
+  }
+
+  // If the target has delay that is larger than 0, hide the target during minimum delay.
+  // The custom alpha function make the target hide just during delay.
+  for(auto&& delay : minimumDelays)
+  {
+    if(delay.second > Dali::Math::MACHINE_EPSILON_10)
+    {
+      Dali::KeyFrames initialKeyframes = Dali::KeyFrames::New();
+      initialKeyframes.Add(0.0f, OPACITY_TRANSPARENT);
+      initialKeyframes.Add(1.0f, delay.first.GetProperty<float>(Dali::Actor::Property::OPACITY));
+
+      AlphaFunction alpha(&CustomAlphaFunction);
+      mAnimation.AnimateBetween(Property(delay.first, Dali::Actor::Property::OPACITY), initialKeyframes, alpha, TimePeriod(delay.second));
+    }
   }
 
   mAnimation.FinishedSignal().Connect(this, &TransitionSet::TransitionFinished);
index ee31d1f..a4903c5 100644 (file)
@@ -239,6 +239,7 @@ TextVisual::TextVisual(VisualFactoryCache& factoryCache)
   mController(Text::Controller::New()),
   mTypesetter(Text::Typesetter::New(mController->GetTextModel())),
   mAnimatableTextColorPropertyIndex(Property::INVALID_INDEX),
+  mTextColorAnimatableIndex(Property::INVALID_INDEX),
   mRendererUpdateNeeded(false)
 {
 }
@@ -290,29 +291,36 @@ void TextVisual::DoSetOnScene(Actor& actor)
   // Enable the pre-multiplied alpha to improve the text quality
   EnablePreMultipliedAlpha(true);
 
-  if(mAnimatableTextColorPropertyIndex != Property::INVALID_INDEX)
+  const Vector4& defaultColor = mController->GetTextModel()->GetDefaultColor();
+  if(mTextColorAnimatableIndex == Property::INVALID_INDEX)
+  {
+    mTextColorAnimatableIndex = mImpl->mRenderer.RegisterProperty("uTextColorAnimatable", defaultColor);
+  }
+  else
   {
-    const Vector4&        defaultColor         = mController->GetTextModel()->GetDefaultColor();
-    Dali::Property::Index shaderTextColorIndex = mImpl->mRenderer.RegisterProperty("uTextColorAnimatable", defaultColor);
+    mImpl->mRenderer.SetProperty(mTextColorAnimatableIndex, defaultColor);
+  }
 
+  if(mAnimatableTextColorPropertyIndex != Property::INVALID_INDEX)
+  {
     // Create constraint for the animatable text's color Property with uTextColorAnimatable in the renderer.
-    if(shaderTextColorIndex != Property::INVALID_INDEX)
+    if(mTextColorAnimatableIndex != Property::INVALID_INDEX)
     {
       if(!mColorConstraint)
       {
-        mColorConstraint = Constraint::New<Vector4>(mImpl->mRenderer, shaderTextColorIndex, TextColorConstraint);
+        mColorConstraint = Constraint::New<Vector4>(mImpl->mRenderer, mTextColorAnimatableIndex, TextColorConstraint);
         mColorConstraint.AddSource(Source(actor, mAnimatableTextColorPropertyIndex));
       }
       mColorConstraint.Apply();
+    }
 
-      // Make zero if the alpha value of text color is zero to skip rendering text
-      if(!mOpacityConstraint)
-      {
-        mOpacityConstraint = Constraint::New<float>(mImpl->mRenderer, Dali::DevelRenderer::Property::OPACITY, OpacityConstraint);
-        mOpacityConstraint.AddSource(Source(actor, mAnimatableTextColorPropertyIndex));
-      }
-      mOpacityConstraint.Apply();
+    // Make zero if the alpha value of text color is zero to skip rendering text
+    if(!mOpacityConstraint)
+    {
+      mOpacityConstraint = Constraint::New<float>(mImpl->mRenderer, Dali::DevelRenderer::Property::OPACITY, OpacityConstraint);
+      mOpacityConstraint.AddSource(Source(actor, mAnimatableTextColorPropertyIndex));
     }
+    mOpacityConstraint.Apply();
   }
 
   // Renderer needs textures and to be added to control
index 7304f0f..f9d6c79 100644 (file)
@@ -336,6 +336,7 @@ private:
   Constraint          mColorConstraint{};                ///< Color constraint
   Constraint          mOpacityConstraint{};              ///< Opacity constraint
   Property::Index     mAnimatableTextColorPropertyIndex; ///< The index of animatable text color property registered by the control.
+  Property::Index     mTextColorAnimatableIndex;         ///< The index of uTextColorAnimatable property.
   bool                mRendererUpdateNeeded : 1;         ///< The flag to indicate whether the renderer needs to be updated.
   RendererContainer   mRendererList;
 };
index 520ffcf..5f6856e 100644 (file)
@@ -29,7 +29,7 @@ namespace Toolkit
 {
 const unsigned int TOOLKIT_MAJOR_VERSION = 2;
 const unsigned int TOOLKIT_MINOR_VERSION = 0;
-const unsigned int TOOLKIT_MICRO_VERSION = 51;
+const unsigned int TOOLKIT_MICRO_VERSION = 52;
 const char* const  TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
diff --git a/dali-toolkit/styles/1920x1080_rpi/dali-toolkit-default-theme.json b/dali-toolkit/styles/1920x1080_rpi/dali-toolkit-default-theme.json
new file mode 100644 (file)
index 0000000..d862b80
--- /dev/null
@@ -0,0 +1,541 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * This file is part of Dali Toolkit
+ *
+ * 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.
+ */
+
+
+//******************************************************************************
+//
+// Default Reference style theme for a 1920x1080 resolution, The values determined by UX design specification.
+// This file can be copied to a new folder within the styles/ directory and amended with new default values.
+// Can be overriden if StyleManager applies another style sheet.
+//
+//******************************************************************************
+
+{
+  "config":
+  {
+    "brokenImageUrl":"{DALI_IMAGE_DIR}broken.png",
+    "alwaysShowFocus":true,
+    "clearFocusOnEscape":false
+  },
+  "styles":
+  {
+    "Tooltip":
+    {
+      "tooltip":
+      {
+        "content":
+        {
+          "pointSize":24
+        },
+        "waitTime":0.5,
+        "background":
+        {
+          "visual":"{DALI_IMAGE_DIR}tooltip.9.png",
+          "border":[1,5,5,1]
+        },
+        "tail":
+        {
+          "visibility":false,
+          "aboveVisual":"{DALI_IMAGE_DIR}tooltip-tail-above.png",
+          "belowVisual":"{DALI_IMAGE_DIR}tooltip-tail-below.png"
+        },
+        "position":"BELOW",
+        "hoverPointOffset":[10,10],
+        "movementThreshold":5,
+        "disappearOnMovement":false
+      }
+    },
+    "TextLabel":
+    {
+      "pointSize":24,
+      "enableAutoScroll":false,
+      "autoScrollLoopCount":2,
+      "autoScrollGap":50,
+      "autoScrollSpeed":80,
+      "ignoreSpacesAfterText":false
+    },
+
+    "TextLabelFontSize0":
+    {
+      "pointSize":24
+    },
+    "TextLabelFontSize1":
+    {
+      "pointSize":28
+    },
+    "TextLabelFontSize2":
+    {
+      "pointSize":32
+    },
+    "TextLabelFontSize3":
+    {
+      "pointSize":36
+    },
+    "TextLabelFontSize4":
+    {
+      "pointSize":40
+    },
+
+    "TextField":
+    {
+      "pointSize":28,
+      "primaryCursorColor":[0.0,0.72,0.9,1.0],
+      "secondaryCursorColor":[0.0,0.72,0.9,1.0],
+      "cursorWidth":6,
+      "selectionHighlightColor":[0.75,0.96,1.0,1.0],
+      "grabHandleImage" : "{DALI_STYLE_IMAGE_DIR}cursor_handler_drop_center.png",
+      "selectionHandleImageLeft" : {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_left.png" },
+      "selectionHandleImageRight": {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_right.png" },
+      "enableSelection":false
+    },
+
+    "TextFieldFontSize0":
+    {
+      "pointSize":24
+    },
+    "TextFieldFontSize1":
+    {
+      "pointSize":28
+    },
+    "TextFieldFontSize2":
+    {
+      "pointSize":32
+    },
+    "TextFieldFontSize3":
+    {
+      "pointSize":36
+    },
+    "TextFieldFontSize4":
+    {
+      "pointSize":40
+    },
+    "TextSelectionPopup":
+    {
+      "popupMaxSize":[1700,100],
+      "optionDividerSize":[2,0],
+      "popupDividerColor":[0.23,0.72,0.8,0.11],
+      "popupIconColor":[1.0,1.0,1.0,1.0],
+      "popupPressedColor":[0.24,0.72,0.8,0.11],
+      "background": {
+        "rendererType": "image",
+        "url": "{DALI_IMAGE_DIR}selection-popup-background.9.png"
+        },
+      "backgroundBorder": {
+        "visualType": "IMAGE",
+        "url": "{DALI_IMAGE_DIR}selection-popup-border.9.png",
+        "mixColor":[0.24,0.72,0.8,1.0]
+        },
+      "popupFadeInDuration":0.25,
+      "popupFadeOutDuration":0.25
+    },
+    "TextSelectionPopupButton":
+    {
+      "label":
+      {
+        "visualType":"TEXT",
+        "pointSize":24
+      },
+      "unselectedBackgroundVisual":
+      {
+        "visualType": "IMAGE",
+        "url": ""
+      },
+      "selectedBackgroundVisual":
+      {
+        "visualType": "IMAGE",
+        "url": ""
+      }
+    },
+    "TextSelectionToolbar":
+    {
+      "enableOvershoot":true,
+      "enableScrollBar":true,
+      "scrollView":
+      {
+        "overshootAnimationSpeed":360.0,
+        "overshootSize":[1920.0,130.0]
+      }
+    },
+    "TextSelectionScrollBar":
+    {
+      "indicatorShowDuration":0.25,
+      "indicatorHideDuration":0.25,
+      "indicatorTransientDuration":1.0
+    },
+    "TextSelectionScrollIndicator":
+    {
+      "image":
+      {
+        "visualType":"IMAGE",
+        "url":"{DALI_IMAGE_DIR}text_selection_scroll_indicator.9.png"
+      },
+      "color":[0.0,0.72,0.9,0.7]
+    },
+    "ScrollView":
+    {
+      "overshootEffectColor":"B018",
+      "overshootAnimationSpeed":960.0,
+      "overshootSize":[1920.0,130.0]
+    },
+    "ItemView":
+    {
+      "overshootEffectColor":"B018",
+      "overshootAnimationSpeed":960.0,
+      "overshootSize":[1920.0,130.0]
+    },
+    "ScrollBar":
+    {
+      "indicatorShowDuration":0.25,
+      "indicatorHideDuration":0.25,
+      "color":[0.0,0.72,0.9,0.7]
+    },
+    "TextEditor":
+    {
+      "pointSize":24,
+      "primaryCursorColor":[0.0,0.72,0.9,1.0],
+      "secondaryCursorColor":[0.0,0.72,0.9,1.0],
+      "cursorWidth":6,
+      "selectionHighlightColor":[0.75,0.96,1.0,1.0],
+      "grabHandleImage" : "{DALI_STYLE_IMAGE_DIR}cursor_handler_drop_center.png",
+      "selectionHandleImageLeft" : {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_left.png" },
+      "selectionHandleImageRight": {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_right.png" },
+      "enableScrollBar":true,
+      "scrollBarShowDuration":0.8,
+      "scrollBarFadeDuration":0.5,
+      "enableSelection":false
+    },
+    "ProgressBar":
+    {
+      "trackVisual":{
+        "visualType":"IMAGE",
+        "url":"{DALI_IMAGE_DIR}progress-bar-skin-track.9.png"
+      },
+      "progressVisual":{
+        "visualType":"IMAGE",
+        "url":"{DALI_IMAGE_DIR}progress-bar-skin-progress.9.png"
+      },
+      "secondaryProgressVisual":{
+        "visualType":"IMAGE",
+        "url":"{DALI_IMAGE_DIR}progress-bar-skin-secondary-progress.9.png"
+      },
+      "indeterminateVisual":{
+        "visualType":"IMAGE",
+        "pixelArea":[0.0, 0.0, 10.0, 1.0],
+        "wrapModeU":"REPEAT",
+        "url":"{DALI_IMAGE_DIR}progress-bar-skin-indeterminate.png"
+      },
+      "indeterminateVisualAnimation":
+      [
+        {
+          "target":"indeterminateVisual",
+          "property":"pixelArea",
+          "initialValue":[0.0, 0.0, 10.0, 1.0],
+          "targetValue":[-1.0, 0.0, 10.0, 1.0],
+          "animator":
+          {
+            "alphaFunction":"DEFAULT",
+            "timePeriod":
+            {
+              "duration":0.8,
+              "delay":0
+            }
+          }
+        }
+      ],
+      "labelVisual":{
+        "visualType": "TEXT",
+        "textColor": [ 1.0, 1.0, 1.0, 1.0 ],
+        "pointSize" : 12.0, // Point size must always be provided to Text Visual
+        "horizontalAlignment": "CENTER",
+        "verticalAlignment": "CENTER"
+      },
+      "progressValue": 0.0,
+      "secondaryProgressValue":0.0,
+      "indeterminate": false
+    },
+    "CircularProgressBar":
+    {
+      "size":[64,64],
+      "trackVisual":{
+        "visualType":"ARC",
+        "mixColor":[0.0,0.165,0.302,1.0],
+        "thickness":4.0,
+        "startAngle":0.0,
+        "cap":"ROUND"
+      },
+      "progressVisual":{
+        "visualType":"ARC",
+        "mixColor":[0.0,0.549,1.0,1.0],
+        "thickness":4.0,
+        "startAngle":0.0,
+        "cap":"ROUND"
+      },
+      "secondaryProgressVisual":{
+        "visualType":"ARC",
+        "mixColor":[0.0,0.549,1.0,0.3],
+        "thickness":4.0,
+        "startAngle":0.0,
+        "cap":"ROUND"
+      },
+      "indeterminateVisual":{
+        "visualType":"ARC",
+        "mixColor":[0.02,0.71,0.525,1.0],
+        "thickness":4.0,
+        "startAngle":267.0,
+        "sweepAngle":75.0,
+        "cap":"ROUND"
+      },
+      "indeterminateVisualAnimation":
+      [
+        {
+          "target":"trackVisual",
+          "property":"opacity",
+          "targetValue": 0,
+          "animator":
+          {
+            "alphaFunction":"DEFAULT",
+            "timePeriod":
+            {
+              "duration":0,
+              "delay":0
+            }
+          }
+        },
+        {
+          "target":"secondaryProgressVisual",
+          "property":"opacity",
+          "targetValue": 0,
+          "animator":
+          {
+            "alphaFunction":"DEFAULT",
+            "timePeriod":
+            {
+              "duration":0,
+              "delay":0
+            }
+          }
+        },
+        {
+          "target":"progressVisual",
+          "property":"sweepAngle",
+          "initialValue": 75,
+          "targetValue": 180,
+          "animator":
+          {
+            "alphaFunction":[0.439, 0.0, 0.718, 0.428],
+            "timePeriod":
+            {
+              "duration":1.0,
+              "delay":0.0
+            }
+          }
+        },
+        {
+          "target":"progressVisual",
+          "property":"sweepAngle",
+          "targetValue": 75,
+          "animator":
+          {
+            "alphaFunction":[0.224, 0.571, 0.53, 1.0],
+            "timePeriod":
+            {
+              "duration":1.0,
+              "delay":2.0
+            }
+          }
+        },
+        {
+          "target":"progressVisual",
+          "property":"startAngle",
+          "initialValue": 87,
+          "targetValue": 1887,
+          "animator":
+          {
+            "alphaFunction":[0.33, 0.0, 0.3, 1.0],
+            "timePeriod":
+            {
+              "duration":3.0,
+              "delay":0.0
+            }
+          }
+        },
+        {
+          "target":"indeterminateVisual",
+          "property":"sweepAngle",
+          "initialValue": 75,
+          "targetValue": 180,
+          "animator":
+          {
+            "alphaFunction":[0.439, 0.0, 0.718, 0.428],
+            "timePeriod":
+            {
+              "duration":1.0,
+              "delay":0.0
+            }
+          }
+        },
+        {
+          "target":"indeterminateVisual",
+          "property":"sweepAngle",
+          "targetValue": 75,
+          "animator":
+          {
+            "alphaFunction":[0.224, 0.571, 0.53, 1.0],
+            "timePeriod":
+            {
+              "duration":1.0,
+              "delay":2.0
+            }
+          }
+        },
+        {
+          "target":"indeterminateVisual",
+          "property":"startAngle",
+          "initialValue": 267,
+          "targetValue": 2067,
+          "animator":
+          {
+            "alphaFunction":[0.33, 0.0, 0.3, 1.0],
+            "timePeriod":
+            {
+              "duration":3.0,
+              "delay":0.0
+            }
+          }
+        }
+      ],
+      "labelVisual":{
+        "visualType": "TEXT",
+        "textColor": [ 1.0, 1.0, 1.0, 1.0 ],
+        "pointSize" : 32.0, // Point size must always be provided to Text Visual
+        "horizontalAlignment": "CENTER",
+        "verticalAlignment": "CENTER"
+      },
+      "progressValue": 0.2,
+      "secondaryProgressValue":0.4,
+      "indeterminate": false
+    },
+    "Button":
+    {
+      "styles":["Tooltip"],
+      "initialAutoRepeatingDelay":2.0,
+      "nextAutoRepeatingDelay":0.9
+      // Note: Visuals added to Button will be used in all derived buttons unless overridden.
+    },
+    "PushButton":
+    {
+      "styles":["Button"],
+      "autoRepeating":false,
+      "togglable":false,
+      "labelPadding":[ 12.0, 12.0, 12.0, 12.0 ],
+      "label":
+       {
+         "visualType": "TEXT",
+         "horizontalAlignment": "CENTER",
+         "pointSize" : 24.0, // Point size must always be provided to Text Visual
+         "verticalAlignment": "CENTER"
+       },
+      "unselectedBackgroundVisual":
+       {
+         "visualType": "IMAGE",
+         "url": "{DALI_IMAGE_DIR}button-up.9.png"
+       },
+       "selectedBackgroundVisual":
+       {
+         "visualType": "IMAGE",
+         "url": "{DALI_IMAGE_DIR}button-down.9.png"
+       },
+       "disabledSelectedBackgroundVisual":
+       {
+         "visualType": "IMAGE",
+         "url": "{DALI_IMAGE_DIR}button-down-disabled.9.png"
+       },
+       "disabledUnselectedBackgroundVisual":
+       {
+         "visualType": "IMAGE",
+         "url": "{DALI_IMAGE_DIR}button-disabled.9.png"
+       }
+    },
+    "ToggleButton":
+    {
+      "styles":["Button"]
+    },
+    "CheckBoxButton":
+    {
+      "styles":["Button"],
+      "labelPadding":[ 12.0, 12.0, 0.0, 0.0 ],
+      "label":
+       {
+         "visualType": "TEXT",
+         "pointSize" : 24.0, // Point size must always be provided to Text Visual
+         "verticalAlignment": "CENTER"
+       },
+      "unselectedVisual":
+      {
+        "visualType": "IMAGE",
+        "url": "{DALI_IMAGE_DIR}checkbox-unselected.png"
+      },
+      "selectedVisual":
+      {
+        "visualType": "IMAGE",
+        "url": "{DALI_IMAGE_DIR}checkbox-selected.png"
+      },
+      "disabledUnselectedVisual":
+      {
+        "visualType": "IMAGE",
+        "url": "{DALI_IMAGE_DIR}checkbox-unselected-disabled.png"
+      },
+      "disabledSelectedVisual":
+      {
+        "visualType": "IMAGE",
+        "url": "{DALI_IMAGE_DIR}checkbox-selected-disabled.png"
+      }
+    },
+    "RadioButton":
+    {
+      "styles":["Button"],
+      "labelPadding":[ 12.0, 12.0, 0.0, 0.0 ],
+      "label":
+       {
+         "visualType": "TEXT",
+         "pointSize" : 24.0, // Point size must always be provided to Text Visual
+         "verticalAlignment": "CENTER"
+       },
+      "unselectedVisual":
+      {
+        "visualType": "IMAGE",
+        "url": "{DALI_IMAGE_DIR}radio-button-unselected.png"
+      },
+      "selectedVisual":
+      {
+        "visualType": "IMAGE",
+        "url": "{DALI_IMAGE_DIR}radio-button-selected.png"
+      },
+      "disabledUnselectedVisual":
+      {
+        "visualType": "IMAGE",
+        "url": "{DALI_IMAGE_DIR}radio-button-unselected-disabled.png"
+      },
+      "disabledSelectedVisual":
+      {
+        "visualType": "IMAGE",
+        "url": "{DALI_IMAGE_DIR}radio-button-selected-disabled.png"
+      }
+    }
+  }
+}
diff --git a/dali-toolkit/styles/1920x1080_rpi/images/cursor_handler_drop_center.png b/dali-toolkit/styles/1920x1080_rpi/images/cursor_handler_drop_center.png
new file mode 100644 (file)
index 0000000..244096f
Binary files /dev/null and b/dali-toolkit/styles/1920x1080_rpi/images/cursor_handler_drop_center.png differ
diff --git a/dali-toolkit/styles/1920x1080_rpi/images/selection_handle_drop_left.png b/dali-toolkit/styles/1920x1080_rpi/images/selection_handle_drop_left.png
new file mode 100644 (file)
index 0000000..244096f
Binary files /dev/null and b/dali-toolkit/styles/1920x1080_rpi/images/selection_handle_drop_left.png differ
diff --git a/dali-toolkit/styles/1920x1080_rpi/images/selection_handle_drop_right.png b/dali-toolkit/styles/1920x1080_rpi/images/selection_handle_drop_right.png
new file mode 100644 (file)
index 0000000..244096f
Binary files /dev/null and b/dali-toolkit/styles/1920x1080_rpi/images/selection_handle_drop_right.png differ
index c572142..d9a1c86 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali2-toolkit
 Summary:    Dali 3D engine Toolkit
-Version:    2.0.51
+Version:    2.0.52
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT
@@ -34,6 +34,7 @@ Requires:   %{name} = %{version}-%{release}
 Conflicts:  %{name}-resources_480x800
 Conflicts:  %{name}-resources_720x1280
 Conflicts:  %{name}-resources_1920x1080
+Conflicts:  %{name}-resources_1920x1080_rpi
 %description resources_360x360
 dali-toolkit default resource files for 360x360
 Contain po / sounds / common images / style / style images
@@ -44,6 +45,7 @@ Requires:   %{name} = %{version}-%{release}
 Conflicts:  %{name}-resources_360x360
 Conflicts:  %{name}-resources_720x1280
 Conflicts:  %{name}-resources_1920x1080
+Conflicts:  %{name}-resources_1920x1080_rpi
 %description resources_480x800
 dali-toolkit default resource files for 480x800
 Contain po / sounds / common images / style / style images
@@ -54,6 +56,7 @@ Requires:   %{name} = %{version}-%{release}
 Conflicts:  %{name}-resources_360x360
 Conflicts:  %{name}-resources_480x800
 Conflicts:  %{name}-resources_1920x1080
+Conflicts:  %{name}-resources_1920x1080_rpi
 %description resources_720x1280
 dali-toolkit default resource files for 720x1280
 Contain po / sounds / common images / style / style images
@@ -64,10 +67,23 @@ Requires:   %{name} = %{version}-%{release}
 Conflicts:  %{name}-resources_360x360
 Conflicts:  %{name}-resources_480x800
 Conflicts:  %{name}-resources_720x1280
+Conflicts:  %{name}-resources_1920x1080_rpi
 %description resources_1920x1080
 dali-toolkit default resource files for 1920x1080
 Contain po / sounds / common images / style / style images
 
+%package resources_1920x1080_rpi
+Summary:    default resource files for 1920x1080 on Raspberry Pi 4
+Requires:   %{name} = %{version}-%{release}
+Conflicts:  %{name}-resources_360x360
+Conflicts:  %{name}-resources_480x800
+Conflicts:  %{name}-resources_720x1280
+Conflicts:  %{name}-resources_1920x1080
+%description resources_1920x1080_rpi
+dali-toolkit default resource files for 1920x1080 on Raspberry Pi 4
+Contain po / sounds / common images / style / style images
+
+
 ##############################
 # devel
 ##############################
@@ -199,6 +215,8 @@ mkdir -p %{buildroot}%{dali_toolkit_style_files}/720x1280
 cp -r dali-toolkit/styles/720x1280/* %{buildroot}%{dali_toolkit_style_files}/720x1280
 mkdir -p %{buildroot}%{dali_toolkit_style_files}/1920x1080
 cp -r dali-toolkit/styles/1920x1080/* %{buildroot}%{dali_toolkit_style_files}/1920x1080
+mkdir -p %{buildroot}%{dali_toolkit_style_files}/1920x1080_rpi
+cp -r dali-toolkit/styles/1920x1080_rpi/* %{buildroot}%{dali_toolkit_style_files}/1920x1080_rpi
 
 # Copy default feedback theme
 cp dali-toolkit/styles/default-feedback-theme.json %{buildroot}%{dali_toolkit_style_files}
@@ -244,6 +262,15 @@ case "$1" in
   ;;
 esac
 
+%pre resources_1920x1080_rpi
+case "$1" in
+  2)
+    pushd %{dali_toolkit_style_files}
+    rm -rf ./*
+    popd
+  ;;
+esac
+
 ##############################
 # Post Install
 ##############################
@@ -271,6 +298,11 @@ pushd %{dali_toolkit_style_files}/1920x1080
 for FILE in *; do mv ./"${FILE}" ../"${FILE}"; done
 popd
 
+%post resources_1920x1080_rpi
+pushd %{dali_toolkit_style_files}/1920x1080_rpi
+for FILE in *; do mv ./"${FILE}" ../"${FILE}"; done
+popd
+
 ##############################
 # Pre Uninstall
 ##############################
@@ -319,6 +351,17 @@ case "$1" in
   ;;
 esac
 
+%preun resources_1920x1080_rpi
+case "$1" in
+  0)
+    %preun resources_1920x1080_rpi
+    pushd %{dali_toolkit_style_files}
+    mv images ./1920x1080_rpi
+    mv dali-toolkit-default-theme.json ./1920x1080_rpi
+    popd
+  ;;
+esac
+
 ##############################
 # Post Uninstall
 ##############################
@@ -362,6 +405,15 @@ case "$1" in
   ;;
 esac
 
+%postun resources_1920x1080_rpi
+case "$1" in
+  0)
+    pushd %{dali_toolkit_style_files}
+    rm -rf *
+    popd
+  ;;
+esac
+
 ##############################
 # Files in Binary Packages
 ##############################
@@ -417,6 +469,15 @@ esac
 %{dali_toolkit_style_files}/default-feedback-theme.json
 %{_datadir}/locale/*/LC_MESSAGES/*
 
+%files resources_1920x1080_rpi
+%manifest dali-toolkit-resources.manifest
+%defattr(-,root,root,-)
+%{dali_toolkit_image_files}/*
+%{dali_toolkit_sound_files}/*
+%{dali_toolkit_style_files}/1920x1080_rpi/*
+%{dali_toolkit_style_files}/default-feedback-theme.json
+%{_datadir}/locale/*/LC_MESSAGES/*
+
 %files -n %{dali2_scene_loader}
 %if 0%{?enable_dali_smack_rules}
 %manifest dali-scene-loader.manifest-smack