From b5d9e85e1551fba1e45ce67e31d1d887a29efd89 Mon Sep 17 00:00:00 2001 From: Sunghyun Kim Date: Tue, 29 Jun 2021 16:38:09 +0900 Subject: [PATCH] Support to use NPatchImage in brokenImage Support to use NpatchImage in broken Image. Application can use custom broken image from this patch. when they set 3 type of broken image(small,normal,large), dali show the proper broken image considering size. Change-Id: I7e2be85d4715d07356fd2782be2d011931fde5c2 --- automated-tests/resources/broken_l.9.png | Bin 0 -> 1850 bytes automated-tests/resources/broken_m.9.png | Bin 0 -> 1376 bytes automated-tests/resources/broken_s.9.png | Bin 0 -> 520 bytes .../src/dali-toolkit/utc-Dali-ImageView.cpp | 97 +++++ .../devel-api/styling/style-manager-devel.cpp | 20 + .../devel-api/styling/style-manager-devel.h | 49 +++ .../internal/styling/style-manager-impl.cpp | 38 ++ .../internal/styling/style-manager-impl.h | 29 +- .../animated-image/animated-image-visual.cpp | 11 +- .../animated-vector-image-visual.cpp | 10 +- .../internal/visuals/image/image-visual.cpp | 54 +-- .../internal/visuals/npatch-loader.cpp | 2 - .../internal/visuals/npatch/npatch-visual.cpp | 9 +- .../internal/visuals/svg/svg-visual.cpp | 14 +- .../internal/visuals/visual-factory-cache.cpp | 359 +++++++++++++++++- .../internal/visuals/visual-factory-cache.h | 113 +++++- .../internal/visuals/visual-factory-impl.cpp | 51 ++- .../internal/visuals/visual-factory-impl.h | 13 + 18 files changed, 780 insertions(+), 89 deletions(-) create mode 100755 automated-tests/resources/broken_l.9.png create mode 100755 automated-tests/resources/broken_m.9.png create mode 100755 automated-tests/resources/broken_s.9.png diff --git a/automated-tests/resources/broken_l.9.png b/automated-tests/resources/broken_l.9.png new file mode 100755 index 0000000000000000000000000000000000000000..48f6078b25f83811a9f220e82588d9a8d8179b5c GIT binary patch literal 1850 zcmb7F4Of##7EU0*yM(|52t+`9lkD-USU|!@_lS`A8j4bcMOllQ09mOb3R$E``3gzU zw{Cz_DV7CRAhn3nD!~T@9t0fQ|r(-eB{xd|wlQKtXv|qo8-*LHh z|NL6^Y~w>9O?x#~TbNMZwx)_J2B0_Uoo2c-lOby8@J6JzmG^%{%f_e$kuz<2_A}Dx`@7enuBS z#%vqU+8+*T4w)Csi#1E)??UnnDT3eY*VR6rnw*}t-wrrWf2m_Nh5d)tmybtV(K;-BriMg_hI+ORm_7i{n>z;Ez zfRVNEFJ1jWPwQU(4ec4-D>;pSZsT7nQvF?W|9p_tmmfW+*bYja22=Epx>CizWGSxE zICF~en@4AwmR438_~HK^Igd&fzv!iyL%!LVUDp95FLyg|CkM)7L*`=^n&9Ypp)p?@ zcV)oR{(fDnIm75-&&16wLIQ2*^bXs~w_JGg@vOrqZVlzd4WA%0akR6Lon)3EF!Emy zH~}t)#4t8z-(C~_NOXhjDVMH^+Tk$YHg>lo26Wm6w`~K;Ct1!|;A_oA`n|b+=~8&I zuy&E6@UAhcHQe!Ta)sN5fuY>0wFEJe{>FEv!j$2$eWE5?RzB9*_|$g$ar9EuKUY^! z$-y>S;LVe3w0+Jwf8f8HyVuRQ?eBpTnLj^6CAD!2Z3RZd>Y!o5JNbww@CuS3Q?0;K zP4m{V3_=oBUEq;-sf01ZGDJDy=wL86qSPO78aDMvYceulT;KV-$)XGZ6Wz1MnVGP4 z%P+6Y_P4Ybz6YuLYg&+9Sq|9C})k~4|<`-L1{j!V#ETS)>XD5y( zQ!T+3;2Jc;j}j_v>)@4GUlTT?0dc6Uq?o7_nAyQzGaro?u#N2!psuD4cF&U$t6AWn z4uK+ZVePi`O=q_=cnF7N;#ECcv}S*FAykG+y2^s03M2oqvCA%3EXs-6w;N6^=QfUs zDydw+Da!xO=)Js6J`@9Kd$yD-80}jS!9A4XuZmaud{$TPAP#CD)td46M3wl=+VO<1 zxKSE}fxB*9Z^(=^0tvuCy>!ORxUf^T(tGQXvbrNz@ZpHdl$)fsBG-!O==F%X@Y=)A zE%o}U>(4n2`>1+WgRp@S5b*R3tB6-w!)>w_NK1LdhZ@wS3O#H!n4v7dUey~U%qemGz-v$7=37`1R` z;Q)ds2lyqtWROe*8Pp~{&EftI=%+j&Q5^gY1>wx8taP0zK04qMUf%~5 z(d`>Q3wLzmAS_w3;Clw0K}vLfm924M;tJl^B+OI+B?c-)L60F(F(i$YI1n1iM$iB3 zjY^J1GUe!b+A@rWeCQm{?yfRKQTzd%W0<4-Z&d`v83PO%6%(Zg;V2hj;Z+0r`Q<3@ zPvDa@>Gf@bQ7hf-hx)q%-2=;o$NF1%dzI<(uA{J)5+!_zrXm^I5?$6+rWChB0;pBv zb*O95DW*ZVV*>+^<-6m)bZv?+qNlg54?(>$H3cCwb?Mj@p*;a5;AP+1hEwe+IrnR} zNU8U59*Jf5R*<#v4Cz=9^E9u4LS#v({}1}*PY72NlbjDe6lFERU(fyY?t`aOvU4)B cjwcb&-&$})Xpmf|2!UBb?CyB%IyY7FU&84Q1ONa4 literal 0 HcmV?d00001 diff --git a/automated-tests/resources/broken_m.9.png b/automated-tests/resources/broken_m.9.png new file mode 100755 index 0000000000000000000000000000000000000000..fd999390f7eedc257335ddd6caf4f513258cd904 GIT binary patch literal 1376 zcmeAS@N?(olHy`uVBq!ia0vp^k3g7%4M+wHNMC1QVCD35aSW+od~<_w`Jn)j10VM} zt#g?aGtRX5*%a*isosLy*_=dY6^F1SIf^4?YVc{kpFmuE_8 zc8XDK;ouM?8t?f1L7Y+1twq4GL%~I{Nq~_~_-B8Rmx-_NWs_Xbb8|M|Zd}hXaVCek z@M75?eF7(2?-*DEUBeaFai%3Bt|i0ptTvD*s2Jt*87StIa#S(u%;S#|*I%1vtu254 z*^;llS)la?pVOWgJwqPnx@Rl5E;^+Gz3;F@W#NSDoPj2!mq&d2GIMoO!E-TN-%$f$Y zKJ{tLnxCm3RhMS(Y*hrgr{mr?{`-k%&X`BbYUa+aFAvL++$PXkA^*td)Wx4Q2cCXC z(~wzsMrd2yv}fO!Jo(FMqXG2V`o{6z{c19Go%rvYpd0 zpg-@mpO8qOX*K!N#OhwvmL8z%_V5Whuz3bN+Z;71E|FD1;f&V1IWr}J0rjHutJtAE zcBfJffWk+RNqbAlwuy$oScqpc)a}}$|4;wYljqNBWrP(Id^&4H7YVf9&{zJ=!T7kQ z?#;}JI)f~M7tsE5+qWy<$9hF_Af6f2Ea{JF2 zi}Nbq1f&#q9p(K{b4;Q}Nn{aYhiFTKVe|tR4HsqsZ4S=G9IYAu7z`cmok?iqY%gY1 zR?yk5Y!p}3?tXwfu!A{q!H1VM=XP&oNL<)!c+A@1H_)A-Ee5;O=JYFkid((hA|U=C z&>Pr!h2207Xzk^HY};6S zz6)|)jM@28++d!YhD$MT=X`uh@oIoL_&GB==MhRg2lGre0?haOFA7mar zckTL9BHJy}j=f^bJAJYK?d3*R1_K7>gKz9hmr92STF5+L%y%((WPhL|!G-qNAjQQX z=_t@D4ds1p4T1+dNWtZ932N*z`&K__(tmydST+ikxJHyjE#rq~xF6hp+)g5^5M=J$ea&66)@HB6UXhtuh+r2E zdpsVY1IAlHvs*yT?7q;ZX>46r+qUh}z?_&{gxDaLwj<2FmfD8E)G)1{6SC!`|ec>sufc z6#FzJl$U-SN56(GfEN&I>5<8O@gRfy;`*tW@O!*ijKvv0r)y7jU2}UvMrk`xQ05U- zl<68i3JP%mCeH4Le){%*zsQ4p*V~?vkJ(MBnpA6tJTsV9W2ah`k<)x*uoOKk#elko> z_;2_9xndHLa #include #include +#include #include #include @@ -61,6 +62,13 @@ const char* TEST_IMAGE_FILE_NAME2 = "gallery_image_02.jpg"; const char* TEST_IMAGE_1 = TEST_RESOURCE_DIR "/TB-gloss.png"; const char* TEST_IMAGE_2 = TEST_RESOURCE_DIR "/tb-norm.png"; +const char* TEST_BROKEN_IMAGE_DEFAULT = TEST_RESOURCE_DIR "/broken.png"; +const char* TEST_BROKEN_IMAGE_S = TEST_RESOURCE_DIR "/broken_s.9.png"; +const char* TEST_BROKEN_IMAGE_M = TEST_RESOURCE_DIR "/broken_m.9.png"; +const char* TEST_BROKEN_IMAGE_L = TEST_RESOURCE_DIR "/broken_l.9.png"; +const char* TEST_BROKEN_IMAGE_01 = TEST_RESOURCE_DIR "/button-up.9.png"; +const char* TEST_BROKEN_IMAGE_02 = TEST_RESOURCE_DIR "/heartsframe.9.png"; + // resolution: 34*34, pixel format: RGBA8888 static const char* gImage_34_RGBA = TEST_RESOURCE_DIR "/icon-edit.png"; // resolution: 600*600, pixel format: RGB888 @@ -2903,6 +2911,95 @@ int UtcDaliImageViewTVGLoading(void) } END_TEST; } +int UtcDaliImageViewImageLoadFailure01(void) +{ + ToolkitTestApplication application; + + Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get(); + DevelStyleManager::SetBrokenImageUrl(styleManager, DevelStyleManager::BrokenImageType::SMALL, TEST_BROKEN_IMAGE_S); + DevelStyleManager::SetBrokenImageUrl(styleManager, DevelStyleManager::BrokenImageType::NORMAL, TEST_BROKEN_IMAGE_M); + DevelStyleManager::SetBrokenImageUrl(styleManager, DevelStyleManager::BrokenImageType::LARGE, TEST_BROKEN_IMAGE_L); + + std::string brokenUrl; + brokenUrl = DevelStyleManager::GetBrokenImageUrl(styleManager, DevelStyleManager::BrokenImageType::SMALL); + DALI_TEST_EQUALS( TEST_BROKEN_IMAGE_S, brokenUrl, TEST_LOCATION); + + brokenUrl = DevelStyleManager::GetBrokenImageUrl(styleManager, DevelStyleManager::BrokenImageType::NORMAL); + DALI_TEST_EQUALS( TEST_BROKEN_IMAGE_M, brokenUrl, TEST_LOCATION); + + brokenUrl = DevelStyleManager::GetBrokenImageUrl(styleManager, DevelStyleManager::BrokenImageType::LARGE); + DALI_TEST_EQUALS( TEST_BROKEN_IMAGE_L, brokenUrl, TEST_LOCATION); + + ImageView imageView = ImageView::New("invalidUrl.png"); + imageView.SetProperty( Actor::Property::SIZE, Vector2( 200.f, 200.f ) ); + + application.GetScene().Add( imageView ); + application.SendNotification(); + application.Render(16); + + // loading started, this waits for the loader thread + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliImageViewImageLoadFailure02(void) +{ + ToolkitTestApplication application; + + Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get(); + DevelStyleManager::SetBrokenImageUrl(styleManager, DevelStyleManager::BrokenImageType::SMALL, TEST_BROKEN_IMAGE_DEFAULT); + DevelStyleManager::SetBrokenImageUrl(styleManager, DevelStyleManager::BrokenImageType::NORMAL, TEST_BROKEN_IMAGE_M); + DevelStyleManager::SetBrokenImageUrl(styleManager, DevelStyleManager::BrokenImageType::LARGE, TEST_BROKEN_IMAGE_L); + + std::string brokenUrl; + brokenUrl = DevelStyleManager::GetBrokenImageUrl(styleManager, DevelStyleManager::BrokenImageType::SMALL); + DALI_TEST_EQUALS( TEST_BROKEN_IMAGE_DEFAULT, brokenUrl, TEST_LOCATION); + + brokenUrl = DevelStyleManager::GetBrokenImageUrl(styleManager, DevelStyleManager::BrokenImageType::NORMAL); + DALI_TEST_EQUALS( TEST_BROKEN_IMAGE_M, brokenUrl, TEST_LOCATION); + + brokenUrl = DevelStyleManager::GetBrokenImageUrl(styleManager, DevelStyleManager::BrokenImageType::LARGE); + DALI_TEST_EQUALS( TEST_BROKEN_IMAGE_L, brokenUrl, TEST_LOCATION); + + ImageView imageView = ImageView::New("invalidUrl.png"); + imageView.SetProperty( Actor::Property::SIZE, Vector2( 30.f, 30.f ) ); + application.GetScene().Add( imageView ); + application.SendNotification(); + application.Render(16); + + // loading started, this waits for the loader thread + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliImageViewImageLoadFailure03(void) +{ + ToolkitTestApplication application; + + Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get(); + DevelStyleManager::SetBrokenImageUrl(styleManager, DevelStyleManager::BrokenImageType::SMALL, TEST_BROKEN_IMAGE_01); + DevelStyleManager::SetBrokenImageUrl(styleManager, DevelStyleManager::BrokenImageType::NORMAL, TEST_BROKEN_IMAGE_02); + + std::string brokenUrl; + brokenUrl = DevelStyleManager::GetBrokenImageUrl(styleManager, DevelStyleManager::BrokenImageType::SMALL); + DALI_TEST_EQUALS( TEST_BROKEN_IMAGE_01, brokenUrl, TEST_LOCATION); + + brokenUrl = DevelStyleManager::GetBrokenImageUrl(styleManager, DevelStyleManager::BrokenImageType::NORMAL); + DALI_TEST_EQUALS( TEST_BROKEN_IMAGE_02, brokenUrl, TEST_LOCATION); + + ImageView imageView = ImageView::New("invalidUrl.png"); + imageView.SetProperty( Actor::Property::SIZE, Vector2( 100.f, 100.f ) ); + application.GetScene().Add( imageView ); + application.SendNotification(); + application.Render(16); + + // loading started, this waits for the loader thread + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); + + END_TEST; +} namespace { diff --git a/dali-toolkit/devel-api/styling/style-manager-devel.cpp b/dali-toolkit/devel-api/styling/style-manager-devel.cpp index 29f0e8bc53..cc96d45ff5 100644 --- a/dali-toolkit/devel-api/styling/style-manager-devel.cpp +++ b/dali-toolkit/devel-api/styling/style-manager-devel.cpp @@ -30,6 +30,26 @@ const Property::Map GetConfigurations(StyleManager styleManager) return GetImpl(styleManager).GetConfigurations(); } +void SetBrokenImageUrl(StyleManager styleManager, DevelStyleManager::BrokenImageType brokenImageType, const std::string& brokenImageUrl) +{ + return GetImpl(styleManager).SetBrokenImageUrl(brokenImageType, brokenImageUrl); +} + +std::string GetBrokenImageUrl(StyleManager styleManager, DevelStyleManager::BrokenImageType brokenImageType) +{ + return GetImpl(styleManager).GetBrokenImageUrl(brokenImageType); +} + +std::vector GetBrokenImageUrlList(StyleManager styleManager) +{ + return GetImpl(styleManager).GetBrokenImageUrlList(); +} + +BrokenImageChangedSignalType& BrokenImageChangedSignal(StyleManager styleManager) +{ + return GetImpl(styleManager).BrokenImageChangedSignal(); +} + } // namespace DevelStyleManager } // namespace Toolkit diff --git a/dali-toolkit/devel-api/styling/style-manager-devel.h b/dali-toolkit/devel-api/styling/style-manager-devel.h index efcff7d5b9..f1e05d7fc0 100644 --- a/dali-toolkit/devel-api/styling/style-manager-devel.h +++ b/dali-toolkit/devel-api/styling/style-manager-devel.h @@ -27,6 +27,18 @@ namespace Toolkit { namespace DevelStyleManager { +/** + * @brief The Type of BrokenImage + */ +enum class BrokenImageType +{ + SMALL, + NORMAL, + LARGE +}; + +using BrokenImageChangedSignalType = Signal; + /** * @brief Gets all currently defined configurations. * @@ -36,6 +48,43 @@ namespace DevelStyleManager **/ DALI_TOOLKIT_API const Property::Map GetConfigurations(StyleManager styleManager); +/** + * @brief Sets an image to be used when a visual has failed to correctly render + * @param[in] styleManager The instance of StyleManager + * @param[in] brokenImageType The type of broken image + * @param[in] brokenImageUrl The broken image url + */ +DALI_TOOLKIT_API void SetBrokenImageUrl(StyleManager styleManager, DevelStyleManager::BrokenImageType brokenImageType, const std::string& brokenImageUrl); + +/** + * @brief Gets an image to be used when a visual has failed to correctly render + * @param[in] styleManager The instance of StyleManager + * @param[in] brokenImageType BrokenImage type + */ +DALI_TOOLKIT_API std::string GetBrokenImageUrl(StyleManager styleManager, DevelStyleManager::BrokenImageType brokenImageType); + +/** + * @brief Get the Broken Image Url List + * + * This list is broken images stored in order of SMALL, NORMAL, and LARGE values except if the value is empty. + * This API just makes the list without comparing size, so the application must set a value that matches the size. + * @param styleManager The instance of StyleManager + * @return A List of Broken Image Url + */ +DALI_TOOLKIT_API std::vector GetBrokenImageUrlList(StyleManager styleManager); + +/** + * @brief This signal is emitted when the URL of the broken image is set + * + * A callback of the following type may be connected: + * @code + * void YourCallbackName(StyleManager styleManager) + * @endcode + * @param styleManager The instance of StyleManager + * @return The signal to connect to + */ +DALI_TOOLKIT_API BrokenImageChangedSignalType& BrokenImageChangedSignal(StyleManager styleManager); + } // namespace DevelStyleManager } // namespace Toolkit diff --git a/dali-toolkit/internal/styling/style-manager-impl.cpp b/dali-toolkit/internal/styling/style-manager-impl.cpp index 0968081cb1..959724b26e 100644 --- a/dali-toolkit/internal/styling/style-manager-impl.cpp +++ b/dali-toolkit/internal/styling/style-manager-impl.cpp @@ -45,6 +45,8 @@ const char* APPLICATION_RESOURCE_PATH_KEY = "APPLICATION_RESOURCE_PATH"; const char* DEFAULT_TOOLKIT_PACKAGE_PATH = "/toolkit/"; +static constexpr int32_t COUNT_BROKEN_IMAGE_MAX = 3; + #if defined(DEBUG_ENABLED) Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_STYLE"); #endif @@ -125,6 +127,9 @@ StyleManager::StyleManager() // Sound & haptic style mFeedbackStyle = new FeedbackStyle(); + + // Initialize BrokenImages + mBrokenImageUrls.assign(COUNT_BROKEN_IMAGE_MAX, ""); } StyleManager::~StyleManager() @@ -230,6 +235,11 @@ Toolkit::StyleManager::StyleChangedSignalType& StyleManager::ControlStyleChangeS return mControlStyleChangeSignal; } +Toolkit::DevelStyleManager::BrokenImageChangedSignalType& StyleManager::BrokenImageChangedSignal() +{ + return mBrokenImageChangedSignal; +} + void StyleManager::SetTheme(const std::string& themeFile) { bool themeLoaded = false; @@ -309,6 +319,34 @@ const Property::Map StyleManager::GetConfigurations() return result; } +void StyleManager::SetBrokenImageUrl(DevelStyleManager::BrokenImageType brokenImageType, const std::string& brokenImageUrl) +{ + int brokenType = static_cast(brokenImageType); + mBrokenImageUrls[brokenType] = brokenImageUrl; + Toolkit::StyleManager styleManager = StyleManager::Get(); + mBrokenImageChangedSignal.Emit(styleManager); +} + +std::string StyleManager::GetBrokenImageUrl(DevelStyleManager::BrokenImageType brokenImageType) +{ + int brokenType = static_cast(brokenImageType); + return mBrokenImageUrls[brokenType]; +} + +std::vector StyleManager::GetBrokenImageUrlList() +{ + // create a list for brokenImage + std::vector brokenImageUrlList; + for(int i = 0; i < COUNT_BROKEN_IMAGE_MAX; i++) + { + if(!mBrokenImageUrls[i].empty()) + { + brokenImageUrlList.push_back(mBrokenImageUrls[i]); + } + } + return brokenImageUrlList; +} + bool StyleManager::LoadFile(const std::string& filename, std::string& stringOut) { DALI_ASSERT_DEBUG(0 != filename.length()); diff --git a/dali-toolkit/internal/styling/style-manager-impl.h b/dali-toolkit/internal/styling/style-manager-impl.h index b6eaff5698..56e61f04ca 100644 --- a/dali-toolkit/internal/styling/style-manager-impl.h +++ b/dali-toolkit/internal/styling/style-manager-impl.h @@ -30,6 +30,7 @@ #include #include #include +#include namespace Dali { @@ -94,6 +95,21 @@ public: // Public API */ const Property::Map GetConfigurations(); + /** + * @copydoc Toolkit::DevelStyleManager::SetBrokenImageUrl + */ + void SetBrokenImageUrl(DevelStyleManager::BrokenImageType brokenImageType, const std::string& brokenImageUrl); + + /** + * @copydoc Toolkit::DevelStyleManager::GetBrokenImageUrl + */ + std::string GetBrokenImageUrl(DevelStyleManager::BrokenImageType brokenImageType); + + /** + * @copydoc Toolkit::DevelStyleManager::GetBrokenImageUrlList + */ + std::vector GetBrokenImageUrlList(); + /** * @brief Apply the theme style to a control. * @@ -136,6 +152,12 @@ public: */ Toolkit::StyleManager::StyleChangedSignalType& ControlStyleChangeSignal(); + /** + * This signal is sent to the visual factory following a broken image change. + * It should not be exposed in the public API + */ + Toolkit::DevelStyleManager::BrokenImageChangedSignalType& BrokenImageChangedSignal(); + private: typedef std::vector StringList; @@ -233,9 +255,12 @@ private: Toolkit::Internal::FeedbackStyle* mFeedbackStyle; ///< Feedback style + std::vector mBrokenImageUrls; ///< Broken Image Urls received from user + // Signals - Toolkit::StyleManager::StyleChangedSignalType mControlStyleChangeSignal; ///< Emitted when the style( theme/font ) changes for the controls to style themselves - Toolkit::StyleManager::StyleChangedSignalType mStyleChangedSignal; ///< Emitted after the controls have been styled + Toolkit::StyleManager::StyleChangedSignalType mControlStyleChangeSignal; ///< Emitted when the style( theme/font ) changes for the controls to style themselves + Toolkit::StyleManager::StyleChangedSignalType mStyleChangedSignal; ///< Emitted after the controls have been styled + Toolkit::DevelStyleManager::BrokenImageChangedSignalType mBrokenImageChangedSignal; ///< Emitted after brokenImageChangedSignal }; } // namespace Internal diff --git a/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp b/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp index da54e1e3e1..9693cc834f 100644 --- a/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp +++ b/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp @@ -807,9 +807,14 @@ TextureSet AnimatedImageVisual::SetLoadingFailed() DALI_LOG_INFO(gAnimImgLogFilter, Debug::Concise, "ResourceReady(ResourceStatus::FAILED)\n"); ResourceReady(Toolkit::Visual::ResourceStatus::FAILED); - TextureSet textureSet = TextureSet::New(); - Texture brokenImage = mFactoryCache.GetBrokenVisualImage(); - textureSet.SetTexture(0u, brokenImage); + Actor actor = mPlacementActor.GetHandle(); + Vector2 imageSize = Vector2::ZERO; + if(actor) + { + imageSize = actor.GetProperty(Actor::Property::SIZE).Get(); + } + mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize); + TextureSet textureSet = mImpl->mRenderer.GetTextures(); if(mFrameDelayTimer) { diff --git a/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp b/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp index 35d7456b89..89d02e8e63 100644 --- a/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp +++ b/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp @@ -305,14 +305,10 @@ void AnimatedVectorImageVisual::DoSetOnScene(Actor& actor) if(mLoadFailed) { - TextureSet textureSet = TextureSet::New(); - mImpl->mRenderer.SetTextures(textureSet); - - Texture brokenImage = mFactoryCache.GetBrokenVisualImage(); - textureSet.SetTexture(0u, brokenImage); - + Vector2 imageSize = Vector2::ZERO; + imageSize = actor.GetProperty(Actor::Property::SIZE).Get(); + mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize); actor.AddRenderer(mImpl->mRenderer); - ResourceReady(Toolkit::Visual::ResourceStatus::FAILED); } else diff --git a/dali-toolkit/internal/visuals/image/image-visual.cpp b/dali-toolkit/internal/visuals/image/image-visual.cpp index 0251a1dad2..7e404ca060 100644 --- a/dali-toolkit/internal/visuals/image/image-visual.cpp +++ b/dali-toolkit/internal/visuals/image/image-visual.cpp @@ -513,8 +513,14 @@ void ImageVisual::GetNaturalSize(Vector2& naturalSize) } else { - Texture brokenImage = mFactoryCache.GetBrokenVisualImage(); - + Actor actor = mPlacementActor.GetHandle(); + Vector2 imageSize = Vector2::ZERO; + if(actor) + { + imageSize = actor.GetProperty(Actor::Property::SIZE).Get(); + } + mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize); + Texture brokenImage = mImpl->mRenderer.GetTextures().GetTexture(0); naturalSize.x = brokenImage.GetWidth(); naturalSize.y = brokenImage.GetWidth(); } @@ -710,12 +716,12 @@ void ImageVisual::DoSetOnScene(Actor& actor) } else if(mLoadState == TextureManager::LoadState::LOAD_FAILED) { - Texture brokenImage = mFactoryCache.GetBrokenVisualImage(); - - mTextures = TextureSet::New(); - mTextures.SetTexture(0u, brokenImage); - mImpl->mRenderer.SetTextures(mTextures); - + Vector2 imageSize = Vector2::ZERO; + if(actor) + { + imageSize = actor.GetProperty(Actor::Property::SIZE).Get(); + } + mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize); actor.AddRenderer(mImpl->mRenderer); mPlacementActor.Reset(); @@ -860,26 +866,30 @@ void ImageVisual::UploadComplete(bool loadingSuccess, int32_t textureId, Texture EnablePreMultipliedAlpha(preMultiplied); Actor actor = mPlacementActor.GetHandle(); - if(actor) + if(!loadingSuccess) { - actor.AddRenderer(mImpl->mRenderer); - // reset the weak handle so that the renderer only get added to actor once - mPlacementActor.Reset(); + Vector2 imageSize = Vector2::ZERO; + if(actor) + { + imageSize = actor.GetProperty(Actor::Property::SIZE).Get(); + } + mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize); + textureSet = mImpl->mRenderer.GetTextures(); } - - if(!loadingSuccess) + else { - Texture brokenImage = mFactoryCache.GetBrokenVisualImage(); - - textureSet = TextureSet::New(); - textureSet.SetTexture(0u, brokenImage); + Sampler sampler = Sampler::New(); + sampler.SetWrapMode(mWrapModeU, mWrapModeV); + textureSet.SetSampler(0u, sampler); mImpl->mRenderer.SetTextures(textureSet); } - Sampler sampler = Sampler::New(); - sampler.SetWrapMode(mWrapModeU, mWrapModeV); - textureSet.SetSampler(0u, sampler); - mImpl->mRenderer.SetTextures(textureSet); + if(actor) + { + actor.AddRenderer(mImpl->mRenderer); + // reset the weak handle so that the renderer only get added to actor once + mPlacementActor.Reset(); + } } // Storing TextureSet needed when renderer staged. diff --git a/dali-toolkit/internal/visuals/npatch-loader.cpp b/dali-toolkit/internal/visuals/npatch-loader.cpp index 5f8ddff06d..cb2850d2f3 100644 --- a/dali-toolkit/internal/visuals/npatch-loader.cpp +++ b/dali-toolkit/internal/visuals/npatch-loader.cpp @@ -104,7 +104,6 @@ std::size_t NPatchLoader::Load(TextureManager& textureManager, TextureUploadObse newData->AddObserver(textureObserver); mCache.PushBack(newData); - return newData->GetId(); // valid ids start from 1u } } @@ -133,7 +132,6 @@ std::size_t NPatchLoader::Load(TextureManager& textureManager, TextureUploadObse preMultiplyOnLoad = (preMultiplyOnLoading == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD) ? true : false; data->SetLoadedNPatchData(pixelBuffer, preMultiplyOnLoad); } - return data->GetId(); } diff --git a/dali-toolkit/internal/visuals/npatch/npatch-visual.cpp b/dali-toolkit/internal/visuals/npatch/npatch-visual.cpp index d9c26aa680..e87e2442af 100644 --- a/dali-toolkit/internal/visuals/npatch/npatch-visual.cpp +++ b/dali-toolkit/internal/visuals/npatch/npatch-visual.cpp @@ -562,7 +562,14 @@ void NPatchVisual::ApplyTextureAndUniforms() DALI_LOG_ERROR("The N patch image '%s' is not a valid N patch image\n", mImageUrl.GetUrl().c_str()); textureSet = TextureSet::New(); - Texture croppedImage = mFactoryCache.GetBrokenVisualImage(); + Actor actor = mPlacementActor.GetHandle(); + Vector2 imageSize = Vector2::ZERO; + if(actor) + { + imageSize = actor.GetProperty(Actor::Property::SIZE).Get(); + } + mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize); + Texture croppedImage = mImpl->mRenderer.GetTextures().GetTexture(0); textureSet.SetTexture(0u, croppedImage); mImpl->mRenderer.RegisterProperty("uFixed[0]", Vector2::ZERO); mImpl->mRenderer.RegisterProperty("uFixed[1]", Vector2::ZERO); diff --git a/dali-toolkit/internal/visuals/svg/svg-visual.cpp b/dali-toolkit/internal/visuals/svg/svg-visual.cpp index 67fd4355dc..5d1fff16ca 100644 --- a/dali-toolkit/internal/visuals/svg/svg-visual.cpp +++ b/dali-toolkit/internal/visuals/svg/svg-visual.cpp @@ -157,9 +157,9 @@ void SvgVisual::DoSetOnScene(Actor& actor) if(mLoadFailed) { - Texture brokenImage = mFactoryCache.GetBrokenVisualImage(); - textureSet.SetTexture(0u, brokenImage); - + Vector2 imageSize = Vector2::ZERO; + imageSize = actor.GetProperty(Actor::Property::SIZE).Get(); + mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize); actor.AddRenderer(mImpl->mRenderer); ResourceReady(Toolkit::Visual::ResourceStatus::FAILED); @@ -327,11 +327,9 @@ void SvgVisual::ApplyRasterizedImage(VectorImageRenderer vectorRenderer, PixelDa Actor actor = mPlacementActor.GetHandle(); if(actor) { - TextureSet textureSet = mImpl->mRenderer.GetTextures(); - - Texture brokenImage = mFactoryCache.GetBrokenVisualImage(); - textureSet.SetTexture(0u, brokenImage); - + Vector2 imageSize = Vector2::ZERO; + imageSize = actor.GetProperty(Actor::Property::SIZE).Get(); + mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize); actor.AddRenderer(mImpl->mRenderer); } diff --git a/dali-toolkit/internal/visuals/visual-factory-cache.cpp b/dali-toolkit/internal/visuals/visual-factory-cache.cpp index b4fde0a814..febd2855c0 100644 --- a/dali-toolkit/internal/visuals/visual-factory-cache.cpp +++ b/dali-toolkit/internal/visuals/visual-factory-cache.cpp @@ -26,6 +26,8 @@ #include #include #include +#include +#include namespace Dali { @@ -33,11 +35,73 @@ namespace Toolkit { namespace Internal { +namespace +{ + +/** + * @brief Creates the geometry formed from the vertices and indices + * + * @param[in] vertices The vertices to generate the geometry from + * @param[in] indices The indices to generate the geometry from + * @return The geometry formed from the vertices and indices + */ +Geometry GenerateGeometry(const Vector& vertices, const Vector& indices) +{ + Property::Map vertexFormat; + vertexFormat["aPosition"] = Property::VECTOR2; + VertexBuffer vertexBuffer = VertexBuffer::New(vertexFormat); + if(vertices.Size() > 0) + { + vertexBuffer.SetData(&vertices[0], vertices.Size()); + } + + // Create the geometry object + Geometry geometry = Geometry::New(); + geometry.AddVertexBuffer(vertexBuffer); + if(indices.Size() > 0) + { + geometry.SetIndexBuffer(&indices[0], indices.Size()); + } + + return geometry; +} + +/** + * @brief Adds the indices to form a quad composed off two triangles where the indices are organised in a grid + * + * @param[out] indices The indices to add to + * @param[in] rowIdx The row index to start the quad + * @param[in] nextRowIdx The index to the next row + */ +void AddQuadIndices(Vector& indices, unsigned int rowIdx, unsigned int nextRowIdx) +{ + indices.PushBack(rowIdx); + indices.PushBack(nextRowIdx + 1); + indices.PushBack(rowIdx + 1); + + indices.PushBack(rowIdx); + indices.PushBack(nextRowIdx); + indices.PushBack(nextRowIdx + 1); +} + +/** + * @brief Adds the vertices to create for npatch + * @param[out] vertices The vertices to add to + * @param[in] x The x value of vector + * @param[in] y The y value of vector + */ +void AddVertex(Vector& vertices, unsigned int x, unsigned int y) +{ + vertices.PushBack(Vector2(x, y)); +} + +} //unnamed namespace + VisualFactoryCache::VisualFactoryCache(bool preMultiplyOnLoad) : mSvgRasterizeThread(NULL), mVectorAnimationManager(), - mBrokenImageUrl(""), - mPreMultiplyOnLoad(preMultiplyOnLoad) + mPreMultiplyOnLoad(preMultiplyOnLoad), + mBrokenImageInfoContainer() { } @@ -104,7 +168,10 @@ ImageAtlasManagerPtr VisualFactoryCache::GetAtlasManager() if(!mAtlasManager) { mAtlasManager = new ImageAtlasManager(); - mAtlasManager->SetBrokenImage(mBrokenImageUrl); + if(!mBrokenImageInfoContainer.empty()) + { + mAtlasManager->SetBrokenImage(mBrokenImageInfoContainer[0].url); + } } return mAtlasManager; @@ -207,20 +274,22 @@ Geometry VisualFactoryCache::CreateGridGeometry(Uint16Pair gridSize) return geometry; } -Texture VisualFactoryCache::GetBrokenVisualImage() +Texture VisualFactoryCache::GetBrokenVisualImage(uint32_t brokenIndex) { - if(!mBrokenImageTexture && mBrokenImageUrl.size()) + if(!(mBrokenImageInfoContainer[brokenIndex].texture)) { - PixelData data; - Devel::PixelBuffer pixelBuffer = LoadImageFromFile(mBrokenImageUrl); + PixelData pixelData; + Devel::PixelBuffer pixelBuffer = LoadImageFromFile(mBrokenImageInfoContainer[brokenIndex].url); if(pixelBuffer) { - data = Devel::PixelBuffer::Convert(pixelBuffer); // takes ownership of buffer - mBrokenImageTexture = Texture::New(Dali::TextureType::TEXTURE_2D, data.GetPixelFormat(), data.GetWidth(), data.GetHeight()); - mBrokenImageTexture.Upload(data); + pixelData = Devel::PixelBuffer::Convert(pixelBuffer); // takes ownership of buffer + mBrokenImageInfoContainer[brokenIndex].texture = Texture::New(Dali::TextureType::TEXTURE_2D, pixelData.GetPixelFormat(), pixelData.GetWidth(), pixelData.GetHeight()); + mBrokenImageInfoContainer[brokenIndex].texture.Upload(pixelData); + mBrokenImageInfoContainer[brokenIndex].width = pixelData.GetWidth(); + mBrokenImageInfoContainer[brokenIndex].height = pixelData.GetHeight(); } } - return mBrokenImageTexture; + return mBrokenImageInfoContainer[brokenIndex].texture; } void VisualFactoryCache::SetPreMultiplyOnLoad(bool preMultiply) @@ -233,16 +302,274 @@ bool VisualFactoryCache::GetPreMultiplyOnLoad() return mPreMultiplyOnLoad; } -void VisualFactoryCache::SetBrokenImageUrl(const std::string& brokenImageUrl) +void VisualFactoryCache::SetBrokenImageUrl(const std::vector& brokenImageUrlList) { - mBrokenImageUrl = brokenImageUrl; + mBrokenImageInfoContainer.clear(); + mBrokenImageInfoContainer.assign(brokenImageUrlList.size(), BrokenImageInfo()); + for(unsigned int i = 0; i < brokenImageUrlList.size(); i++) + { + mBrokenImageInfoContainer[i].url = brokenImageUrlList[i]; + } +} - if(!mAtlasManager) +VisualUrl::Type VisualFactoryCache::GetBrokenImageVisualType(int index) +{ + return mBrokenImageInfoContainer[index].visualType; +} + +Geometry VisualFactoryCache::CreateNPatchGeometry(Uint16Pair gridSize) +{ + uint16_t gridWidth = gridSize.GetWidth(); + uint16_t gridHeight = gridSize.GetHeight(); + + // Create vertices + Vector vertices; + vertices.Reserve((gridWidth + 1) * (gridHeight + 1)); + + for(int y = 0; y < gridHeight + 1; ++y) { - mAtlasManager = new ImageAtlasManager(); + for(int x = 0; x < gridWidth + 1; ++x) + { + AddVertex(vertices, x, y); + } + } + + // Create indices + Vector indices; + indices.Reserve(gridWidth * gridHeight * 6); + + unsigned int rowIdx = 0; + unsigned int nextRowIdx = gridWidth + 1; + for(int y = 0; y < gridHeight; ++y, ++nextRowIdx, ++rowIdx) + { + for(int x = 0; x < gridWidth; ++x, ++nextRowIdx, ++rowIdx) + { + AddQuadIndices(indices, rowIdx, nextRowIdx); + } + } + + return GenerateGeometry(vertices, indices); +} + +Geometry VisualFactoryCache::GetNPatchGeometry(int index) +{ + Geometry geometry; + const NPatchData* data; + if(mNPatchLoader.GetNPatchData(mBrokenImageInfoContainer[index].npatchId, data) && data->GetLoadingState() == NPatchData::LoadingState::LOAD_COMPLETE) + { + if(data->GetStretchPixelsX().Size() == 1 && data->GetStretchPixelsY().Size() == 1) + { + geometry = GetGeometry(VisualFactoryCache::NINE_PATCH_GEOMETRY); + if(!geometry) + { + geometry = CreateNPatchGeometry(Uint16Pair(3,3)); + SaveGeometry(VisualFactoryCache::NINE_PATCH_GEOMETRY, geometry); + } + } + else if(data->GetStretchPixelsX().Size() > 0 || data->GetStretchPixelsY().Size() > 0) + { + Uint16Pair gridSize(2 * data->GetStretchPixelsX().Size() + 1, 2 * data->GetStretchPixelsY().Size() + 1); + geometry = CreateNPatchGeometry(gridSize); + } + } + else + { + // no N patch data so use default geometry + geometry = GetGeometry(VisualFactoryCache::NINE_PATCH_GEOMETRY); + if(!geometry) + { + geometry = CreateNPatchGeometry(Uint16Pair(3,3)); + SaveGeometry(VisualFactoryCache::NINE_PATCH_GEOMETRY, geometry); + } + } + return geometry; +} + +Shader VisualFactoryCache::GetNPatchShader(int index) +{ + Shader shader; + const NPatchData* data; + // 0 is either no data (load failed?) or no stretch regions on image + // for both cases we use the default shader + NPatchUtility::StretchRanges::SizeType xStretchCount = 0; + NPatchUtility::StretchRanges::SizeType yStretchCount = 0; + + // ask loader for the regions + if(mNPatchLoader.GetNPatchData(mBrokenImageInfoContainer[index].npatchId, data)) + { + xStretchCount = data->GetStretchPixelsX().Count(); + yStretchCount = data->GetStretchPixelsY().Count(); + } + + if(DALI_LIKELY((xStretchCount == 0 && yStretchCount == 0))) + { + shader = GetShader(VisualFactoryCache::NINE_PATCH_SHADER); + if(DALI_UNLIKELY(!shader)) + { + shader = Shader::New(SHADER_NPATCH_VISUAL_3X3_SHADER_VERT, SHADER_NPATCH_VISUAL_SHADER_FRAG); + + // Only cache vanilla 9 patch shaders + SaveShader(VisualFactoryCache::NINE_PATCH_SHADER, shader); + } + } + else if(xStretchCount > 0 || yStretchCount > 0) + { + std::stringstream vertexShader; + vertexShader << "#define FACTOR_SIZE_X " << xStretchCount + 2 << "\n" + << "#define FACTOR_SIZE_Y " << yStretchCount + 2 << "\n" + << SHADER_NPATCH_VISUAL_SHADER_VERT; + shader = Shader::New(vertexShader.str(), SHADER_NPATCH_VISUAL_SHADER_FRAG); + } + return shader; +} + +void VisualFactoryCache::RegisterStretchProperties(Renderer& renderer, const char* uniformName, const NPatchUtility::StretchRanges& stretchPixels, uint16_t imageExtent) +{ + uint16_t prevEnd = 0; + uint16_t prevFix = 0; + uint16_t prevStretch = 0; + unsigned int i = 1; + for(NPatchUtility::StretchRanges::ConstIterator it = stretchPixels.Begin(); it != stretchPixels.End(); ++it, ++i) + { + uint16_t start = it->GetX(); + uint16_t end = it->GetY(); + + uint16_t fix = prevFix + start - prevEnd; + uint16_t stretch = prevStretch + end - start; + + std::stringstream uniform; + uniform << uniformName << "[" << i << "]"; + renderer.RegisterProperty(uniform.str(), Vector2(fix, stretch)); + + prevEnd = end; + prevFix = fix; + prevStretch = stretch; + } + + { + prevFix += imageExtent - prevEnd; + std::stringstream uniform; + uniform << uniformName << "[" << i << "]"; + renderer.RegisterProperty(uniform.str(), Vector2(prevFix, prevStretch)); + } +} + +void VisualFactoryCache::ApplyTextureAndUniforms(Renderer& renderer, int index) +{ + const NPatchData* data; + TextureSet textureSet; + if(mNPatchLoader.GetNPatchData(mBrokenImageInfoContainer[index].npatchId, data) && data->GetLoadingState() == NPatchData::LoadingState::LOAD_COMPLETE) + { + textureSet = data->GetTextures(); + mBrokenImageInfoContainer[index].texture = data->GetTextures().GetTexture(0); + + if(data->GetStretchPixelsX().Size() == 1 && data->GetStretchPixelsY().Size() == 1) + { + //special case for 9 patch + Uint16Pair stretchX = data->GetStretchPixelsX()[0]; + Uint16Pair stretchY = data->GetStretchPixelsY()[0]; + + uint16_t stretchWidth = (stretchX.GetY() >= stretchX.GetX()) ? stretchX.GetY() - stretchX.GetX() : 0; + uint16_t stretchHeight = (stretchY.GetY() >= stretchY.GetX()) ? stretchY.GetY() - stretchY.GetX() : 0; + + renderer.RegisterProperty("uFixed[0]", Vector2::ZERO); + renderer.RegisterProperty("uFixed[1]", Vector2(stretchX.GetX(), stretchY.GetX())); + renderer.RegisterProperty("uFixed[2]", Vector2(data->GetCroppedWidth() - stretchWidth, data->GetCroppedHeight() - stretchHeight)); + renderer.RegisterProperty("uStretchTotal", Vector2(stretchWidth, stretchHeight)); + } + else + { + renderer.RegisterProperty("uNinePatchFactorsX[0]", Vector2::ZERO); + renderer.RegisterProperty("uNinePatchFactorsY[0]", Vector2::ZERO); + + RegisterStretchProperties(renderer, "uNinePatchFactorsX", data->GetStretchPixelsX(), data->GetCroppedWidth()); + RegisterStretchProperties(renderer, "uNinePatchFactorsY", data->GetStretchPixelsY(), data->GetCroppedHeight()); + } + renderer.SetTextures(textureSet); + } +} + +void VisualFactoryCache::UpdateBrokenImageRenderer(Renderer& renderer, const Vector2& size) +{ + // Load Information for broken image + for(uint32_t index = 0; index < mBrokenImageInfoContainer.size(); index++) + { + if(mBrokenImageInfoContainer[index].width == 0 && mBrokenImageInfoContainer[index].height == 0) + { + if(!mBrokenImageInfoContainer[index].url.empty()) + { + VisualUrl visualUrl(mBrokenImageInfoContainer[index].url); + mBrokenImageInfoContainer[index].visualType = visualUrl.GetType(); + if(mBrokenImageInfoContainer[index].visualType == VisualUrl::Type::N_PATCH) + { + const NPatchData* data; + Rect border; + mBrokenImageInfoContainer[index].npatchId = mNPatchLoader.Load( mTextureManager, NULL, mBrokenImageInfoContainer[index].url, border, mPreMultiplyOnLoad, true); + if(mNPatchLoader.GetNPatchData(mBrokenImageInfoContainer[index].npatchId, data) && data->GetLoadingState() == NPatchData::LoadingState::LOAD_COMPLETE) + { + mBrokenImageInfoContainer[index].width = data->GetCroppedWidth(); + mBrokenImageInfoContainer[index].height = data->GetCroppedHeight(); + } + else + { + DALI_LOG_ERROR("Can't update renderer for broken image. maybe image loading is failed [path:%s] \n",mBrokenImageInfoContainer[index].url.c_str()); + } + } + else + { + GetBrokenVisualImage(index); + } + } + } + } + + // Set Texutre to renderer + int brokenIndex = GetProperBrokenImageIndex(size); + if(GetBrokenImageVisualType(brokenIndex) == VisualUrl::N_PATCH) + { + // Set geometry and shader for npatch + Geometry geometry = GetNPatchGeometry(brokenIndex); + Shader shader = GetNPatchShader(brokenIndex); + renderer.SetGeometry(geometry); + renderer.SetShader(shader); + ApplyTextureAndUniforms(renderer, brokenIndex); + } + else + { + Texture brokenImage = GetBrokenVisualImage(brokenIndex); + TextureSet textureSet = TextureSet::New(); + textureSet.SetTexture(0u, brokenImage); + renderer.SetTextures(textureSet); + } +} + +int32_t VisualFactoryCache::GetProperBrokenImageIndex(const Vector2& size) +{ + // Sets the default broken type + int32_t returnIndex = 0; + if((size.width == 0 || size.height == 0)) + { + // To do : Need to add observer about size + return returnIndex; + } + + // Find the proper value if we know the size of the image + for(int32_t index = static_cast(mBrokenImageInfoContainer.size()) - 1; index >= 0; index--) + { + // Skip if the value is not set + if(mBrokenImageInfoContainer[index].width == 0 || mBrokenImageInfoContainer[index].height == 0) + { + continue; + } + + if(mBrokenImageInfoContainer[index].width < size.width && mBrokenImageInfoContainer[index].height < size.height) + { + returnIndex = index; + break; + } } - mAtlasManager->SetBrokenImage(mBrokenImageUrl); + return returnIndex; } } // namespace Internal diff --git a/dali-toolkit/internal/visuals/visual-factory-cache.h b/dali-toolkit/internal/visuals/visual-factory-cache.h index 6e8f37dd06..b23c0101cd 100644 --- a/dali-toolkit/internal/visuals/visual-factory-cache.h +++ b/dali-toolkit/internal/visuals/visual-factory-cache.h @@ -28,6 +28,7 @@ #include #include #include +#include namespace Dali { @@ -176,12 +177,6 @@ public: */ static Geometry CreateGridGeometry(Uint16Pair gridSize); - /** - * @brief Returns a new Texture to use when a visual has failed to correctly render - * @return The broken image texture. - */ - Texture GetBrokenVisualImage(); - /** * @copydoc Toolkit::VisualFactory::SetPreMultiplyOnLoad() */ @@ -194,9 +189,16 @@ public: /** * @brief Set an image to be used when a visual has failed to correctly render - * @param[in] brokenImageUrl The broken image url. + * @param[in] brokenImageUrlList The broken image url list */ - void SetBrokenImageUrl(const std::string& brokenImageUrl); + void SetBrokenImageUrl(const std::vector& brokenImageUrlList); + + /** + * @brief Update the broken image Renderer object + * @param[in,out] renderer renderer for broken image + * @param[in] size the size of actor + */ + void UpdateBrokenImageRenderer(Renderer& renderer, const Vector2& size); public: /** @@ -241,17 +243,108 @@ protected: VisualFactoryCache& operator=(const VisualFactoryCache& rhs); private: + /** + * @brief Returns a cached Texture to use when a visual has failed to correctly render + * @param[in] brokenIndex The index of broken image + * + * @return The broken image texture. + */ + Texture GetBrokenVisualImage(uint32_t brokenIndex); + + /** + * @brief Gets the Proper broken image index + * @param[in] size The size of actor + * + * @return The index of broken image + */ + int32_t GetProperBrokenImageIndex(const Vector2& size); + + /** + * @brief Apply a texture and uniforms + * + * @param[in,out] renderer The renderer for broken image + * @param[in] index The index of broken image + */ + void ApplyTextureAndUniforms(Renderer& renderer, int index); + + /** + * @brief Creates a Npatch Geometry object + * + * @param[in] gridSize The gridSize for creating a geometry + * @return The Geometry for NPatch + */ + Geometry CreateNPatchGeometry(Uint16Pair gridSize); + + /** + * @brief Gets a geometry for npatch image + * + * @param[in] index the index of broken image + * @return The Geometry for NPatch + */ + Geometry GetNPatchGeometry(int index); + + /** + * @brief Gets the Npatch Shader object + * + * @param[in] index The index of broken image + * @return The Shader for NPatch + */ + Shader GetNPatchShader(int index); + + /** + * @brief Registers a properties for Stretch Ranges + * + * @param[in,out] renderer The renderer for broken image + * @param[in] uniformName The name of the uniform + * @param[in] stretchPixels The stretchable pixels in the cropped image space + * @param[in] imageExtent The imageExtent + */ + void RegisterStretchProperties(Renderer& renderer, const char* uniformName, const NPatchUtility::StretchRanges& stretchPixels, uint16_t imageExtent); + + /** + * @brief Returns a broken image type + * @param[in] index BrokenImage index + * @return The broken image type. + */ + VisualUrl::Type GetBrokenImageVisualType(int index); + +private: + struct BrokenImageInfo + { + BrokenImageInfo() + :visualType(), + url(""), + npatchId(NPatchData::INVALID_NPATCH_DATA_ID), + texture(), + width(0), + height(0) + { + } + + ~BrokenImageInfo() + { + } + + // Data + VisualUrl::Type visualType; + std::string url; + NPatchData::NPatchDataId npatchId; + Texture texture; + uint32_t width; + uint32_t height; + }; + Geometry mGeometry[GEOMETRY_TYPE_MAX + 1]; Shader mShader[SHADER_TYPE_MAX + 1]; ImageAtlasManagerPtr mAtlasManager; TextureManager mTextureManager; NPatchLoader mNPatchLoader; - Texture mBrokenImageTexture; + SvgRasterizeThread* mSvgRasterizeThread; std::unique_ptr mVectorAnimationManager; - std::string mBrokenImageUrl; bool mPreMultiplyOnLoad; + std::vector mBrokenImageInfoContainer; }; } // namespace Internal diff --git a/dali-toolkit/internal/visuals/visual-factory-impl.cpp b/dali-toolkit/internal/visuals/visual-factory-impl.cpp index b86dcf0dd5..112fdd39f4 100644 --- a/dali-toolkit/internal/visuals/visual-factory-impl.cpp +++ b/dali-toolkit/internal/visuals/visual-factory-impl.cpp @@ -91,19 +91,15 @@ void VisualFactory::OnStyleChangedSignal(Toolkit::StyleManager styleManager, Sty { if(type == StyleChange::THEME_CHANGE) { - const std::string imageDirPath = AssetManager::GetDaliImagePath(); - std::string brokenImageUrl = imageDirPath + BROKEN_IMAGE_FILE_NAME; - - Property::Map config = Toolkit::DevelStyleManager::GetConfigurations(styleManager); - config["brokenImageUrl"].Get(brokenImageUrl); - - if(mFactoryCache) - { - mFactoryCache->SetBrokenImageUrl(brokenImageUrl); - } + SetBrokenImageUrl(styleManager); } } +void VisualFactory::OnBrokenImageChangedSignal(Toolkit::StyleManager styleManager) +{ + SetBrokenImageUrl(styleManager); +} + Toolkit::Visual::Base VisualFactory::CreateVisual(const Property::Map& propertyMap) { Visual::BasePtr visualPtr; @@ -372,24 +368,43 @@ Internal::TextureManager& VisualFactory::GetTextureManager() return GetFactoryCache().GetTextureManager(); } +void VisualFactory::SetBrokenImageUrl(Toolkit::StyleManager& styleManager) +{ + const std::string imageDirPath = AssetManager::GetDaliImagePath(); + std::string brokenImageUrl = imageDirPath + BROKEN_IMAGE_FILE_NAME; + std::vector customBrokenImageUrlList; + + if(styleManager) + { + customBrokenImageUrlList = Toolkit::DevelStyleManager::GetBrokenImageUrlList(styleManager); + if(customBrokenImageUrlList.size() == 0) + { + Property::Map config = Toolkit::DevelStyleManager::GetConfigurations(styleManager); + config["brokenImageUrl"].Get(brokenImageUrl); + customBrokenImageUrlList.push_back(brokenImageUrl); + } + mFactoryCache->SetBrokenImageUrl(customBrokenImageUrlList); + } + else + { + // Set default image + customBrokenImageUrlList.push_back(brokenImageUrl); + mFactoryCache->SetBrokenImageUrl(customBrokenImageUrlList); + } +} + Internal::VisualFactoryCache& VisualFactory::GetFactoryCache() { if(!mFactoryCache) { mFactoryCache = std::unique_ptr(new VisualFactoryCache(mPreMultiplyOnLoad)); - - const std::string imageDirPath = AssetManager::GetDaliImagePath(); - std::string brokenImageUrl = imageDirPath + BROKEN_IMAGE_FILE_NAME; - Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get(); if(styleManager) { - Property::Map config = Toolkit::DevelStyleManager::GetConfigurations(styleManager); - config["brokenImageUrl"].Get(brokenImageUrl); styleManager.StyleChangedSignal().Connect(mSlotDelegate, &VisualFactory::OnStyleChangedSignal); + Toolkit::DevelStyleManager::BrokenImageChangedSignal(styleManager).Connect(mSlotDelegate, &VisualFactory::OnBrokenImageChangedSignal); } - - mFactoryCache->SetBrokenImageUrl(brokenImageUrl); + SetBrokenImageUrl(styleManager); } return *mFactoryCache; } diff --git a/dali-toolkit/internal/visuals/visual-factory-impl.h b/dali-toolkit/internal/visuals/visual-factory-impl.h index f038301252..a5ecda81bc 100644 --- a/dali-toolkit/internal/visuals/visual-factory-impl.h +++ b/dali-toolkit/internal/visuals/visual-factory-impl.h @@ -57,6 +57,13 @@ public: */ void OnStyleChangedSignal(Toolkit::StyleManager styleManager, StyleChange::Type type); + /** + * @brief BrokenImageChanged callback + * + * @param[in] styleManager Handle for style manager. + */ + void OnBrokenImageChangedSignal(Toolkit::StyleManager styleManager); + /** * @copydoc Toolkit::VisualFactory::CreateVisual( const Property::Map& ) */ @@ -89,6 +96,12 @@ protected: ~VisualFactory() override; private: + /** + * @brief Set the Broken Image url + * @param[in] styleManager The instance of StyleManager + */ + void SetBrokenImageUrl(Toolkit::StyleManager& styleManager); + /** * Get the factory cache, creating it if necessary. */ -- 2.34.1