[dali_1.2.59] Merge branch 'devel/master' 91/153791/1
authorFrancisco Santos <f1.santos@samsung.com>
Fri, 29 Sep 2017 12:20:15 +0000 (13:20 +0100)
committerFrancisco Santos <f1.santos@samsung.com>
Fri, 29 Sep 2017 12:20:15 +0000 (13:20 +0100)
Change-Id: I655a1a5b9abfab418daefabe1e7158a24574bae2

21 files changed:
automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp
dali-toolkit/devel-api/controls/text-controls/text-field-devel.h
dali-toolkit/devel-api/file.list
dali-toolkit/internal/controls/text-controls/text-field-impl.cpp
dali-toolkit/internal/text/rendering/text-typesetter.cpp
dali-toolkit/internal/text/text-controller-impl.cpp
dali-toolkit/internal/text/text-controller-impl.h
dali-toolkit/internal/text/text-controller.cpp
dali-toolkit/internal/text/text-controller.h
dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp
dali-toolkit/internal/visuals/image/image-visual.cpp
dali-toolkit/internal/visuals/image/image-visual.h
dali-toolkit/internal/visuals/text/text-visual.cpp
dali-toolkit/internal/visuals/text/text-visual.h
dali-toolkit/internal/visuals/texture-manager-impl.cpp
dali-toolkit/internal/visuals/texture-manager-impl.h
dali-toolkit/internal/visuals/visual-factory-cache.h
dali-toolkit/public-api/dali-toolkit-version.cpp
packaging/dali-toolkit.spec

index 31909d9..bac289e 100644 (file)
@@ -24,6 +24,7 @@
 #include <dali/devel-api/scripting/scripting.h>
 #include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
 #include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/devel-api/image-loader/texture-manager.h>
 #include <dali/public-api/rendering/renderer.h>
 
 #include <test-native-image.h>
@@ -589,7 +590,6 @@ int UtcDaliImageViewSyncLoading(void)
   END_TEST;
 }
 
-
 int UtcDaliImageViewSyncLoading02(void)
 {
   ToolkitTestApplication application;
@@ -626,6 +626,30 @@ int UtcDaliImageViewSyncLoading02(void)
   END_TEST;
 }
 
+int UtcDaliImageViewAddedTexture(void)
+{
+  ToolkitTestApplication application;
+
+  tet_infoline("ImageView Testing image view with texture provided manager url");
+
+  ImageView imageView = ImageView::New();
+
+  // empty texture is ok, though pointless from app point of view
+  TextureSet  empty;
+  std::string url = TextureManager::AddTexture(empty);
+  DALI_TEST_CHECK(url.size() > 0u);
+
+  Property::Map propertyMap;
+  propertyMap[ImageVisual::Property::URL] = url;
+  imageView.SetProperty(ImageView::Property::IMAGE, propertyMap);
+
+  Stage::GetCurrent().Add( imageView );
+  application.SendNotification();
+  application.Render();
+
+  END_TEST;
+}
+
 int UtcDaliImageViewSizeWithBackground(void)
 {
   ToolkitTestApplication application;
index a7389b0..df0a150 100644 (file)
@@ -100,6 +100,7 @@ const char* const PROPERTY_NAME_HIDDEN_INPUT_SETTINGS                = "hiddenIn
 const char* const PROPERTY_NAME_PIXEL_SIZE                           = "pixelSize";
 const char* const PROPERTY_NAME_ENABLE_SELECTION                     = "enableSelection";
 const char* const PROPERTY_NAME_PLACEHOLDER                          = "placeholder";
+const char* const PROPERTY_NAME_ELLIPSIS                             = "ellipsis";
 
 const int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::Text::DEFAULT_RENDERING_BACKEND;
 
@@ -513,6 +514,7 @@ int UtcDaliTextFieldGetPropertyP(void)
   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_PIXEL_SIZE ) == DevelTextField::Property::PIXEL_SIZE );
   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_ENABLE_SELECTION ) == DevelTextField::Property::ENABLE_SELECTION );
   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_PLACEHOLDER ) == DevelTextField::Property::PLACEHOLDER );
+  DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_ELLIPSIS ) == DevelTextField::Property::ELLIPSIS );
 
   END_TEST;
 }
@@ -875,6 +877,7 @@ int UtcDaliTextFieldSetPropertyP(void)
   placeholderPixelSizeMapSet["placeholderColor"] = Color::BLUE;
   placeholderPixelSizeMapSet["placeholderFontFamily"] = "Arial";
   placeholderPixelSizeMapSet["placeholderPixelSize"] = 15.0f;
+  placeholderPixelSizeMapSet["placeholderEllipsis"] = true;
 
   placeholderFontstyleMap.Insert( "weight", "bold" );
   placeholderPixelSizeMapSet["placeholderFontStyle"] = placeholderFontstyleMap;
@@ -892,6 +895,7 @@ int UtcDaliTextFieldSetPropertyP(void)
   placeholderMapSet["placeholderColor"] = Color::RED;
   placeholderMapSet["placeholderFontFamily"] = "Arial";
   placeholderMapSet["placeholderPointSize"] = 12.0f;
+  placeholderMapSet["placeholderEllipsis"] = false;
 
   // Check the placeholder font style property
   placeholderFontstyleMap.Clear();
@@ -932,6 +936,11 @@ int UtcDaliTextFieldSetPropertyP(void)
   DALI_TEST_EQUALS( placeholderMapGet.Count(), placeholderMapSet.Count(), TEST_LOCATION );
   DALI_TEST_EQUALS( DaliTestCheckMaps( placeholderMapGet, placeholderMapSet ), true, TEST_LOCATION );
 
+  // Check the ellipsis property
+  DALI_TEST_CHECK( !field.GetProperty<bool>( DevelTextField::Property::ELLIPSIS ) );
+  field.SetProperty( DevelTextField::Property::ELLIPSIS, true );
+  DALI_TEST_CHECK( field.GetProperty<bool>( DevelTextField::Property::ELLIPSIS ) );
+
   END_TEST;
 }
 
index 2f2e692..1130c39 100644 (file)
@@ -222,6 +222,8 @@ int UtcDaliToolkitTextLabelSetPropertyP(void)
   TextLabel label = TextLabel::New();
   DALI_TEST_CHECK( label );
 
+  Stage::GetCurrent().Add( label );
+
   // Note - we can't check the defaults since the stylesheets are platform-specific
   label.SetProperty( TextLabel::Property::RENDERING_BACKEND, Text::RENDERING_SHARED_ATLAS );
   DALI_TEST_EQUALS( (Text::RenderingType)label.GetProperty<int>( TextLabel::Property::RENDERING_BACKEND ), Text::RENDERING_SHARED_ATLAS, TEST_LOCATION );
@@ -345,6 +347,13 @@ int UtcDaliToolkitTextLabelSetPropertyP(void)
   label.SetProperty( TextLabel::Property::ENABLE_MARKUP, true );
   DALI_TEST_CHECK( label.GetProperty<bool>( TextLabel::Property::ENABLE_MARKUP ) );
 
+  // Check the text property when markup is enabled
+  label.SetProperty( TextLabel::Property::TEXT, "<color value='white'>Markup</color><color value='cyan'>Text</color>" );
+  DALI_TEST_EQUALS( label.GetProperty<std::string>( TextLabel::Property::TEXT ), std::string("MarkupText"), TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
   // Check autoscroll properties
   const int SCROLL_SPEED = 80;
   const int SCROLL_LOOPS = 4;
@@ -388,6 +397,9 @@ int UtcDaliToolkitTextLabelSetPropertyP(void)
 
   label.SetProperty( TextLabel::Property::UNDERLINE, underlineMapSet );
 
+  application.SendNotification();
+  application.Render();
+
   underlineMapGet = label.GetProperty<Property::Map>( TextLabel::Property::UNDERLINE );
   DALI_TEST_EQUALS( underlineMapGet.Count(), underlineMapSet.Count(), TEST_LOCATION );
   DALI_TEST_EQUALS( DaliTestCheckMaps( underlineMapGet, underlineMapSet ), true, TEST_LOCATION );
@@ -558,6 +570,11 @@ int UtcDaliToolkitTextLabelEmojisP(void)
   label.SetProperty( TextLabel::Property::ENABLE_MARKUP, true );
   label.SetProperty( TextLabel::Property::TEXT, emojis );
 
+  Property::Map shadowMap;
+  shadowMap.Insert( "color", "green" );
+  shadowMap.Insert( "offset", "2 2" );
+  label.SetProperty( TextLabel::Property::SHADOW, shadowMap );
+
   application.SendNotification();
   application.Render();
 
index bc199ad..4369126 100644 (file)
@@ -116,6 +116,7 @@ namespace Property
        *   propertyMap["placeholderColor"] = Color::RED;
        *   propertyMap["placeholderFontFamily"] = "Arial";
        *   propertyMap["placeholderPointSize"] = 12.0f;
+       *   propertyMap["placeholderEllipsis"] = true;
        *
        *   Property::Map fontStyleMap;
        *   fontStyleMap.Insert( "weight", "bold" );
@@ -128,7 +129,14 @@ namespace Property
        *
        * @details name "placeholder", type MAP
        */
-      PLACEHOLDER = INPUT_OUTLINE + 4
+      PLACEHOLDER = INPUT_OUTLINE + 4,
+
+      /**
+       * @brief Enable or disable the ellipsis.
+       * @details name "ellipsis", type Property::BOOLEAN.
+       * @note PLACEHOLDER map is used to add ellipsis to placeholder text.
+       */
+      ELLIPSIS = INPUT_OUTLINE + 5
   };
 } // namespace Property
 
index 5cf6797..85275d9 100644 (file)
@@ -117,7 +117,8 @@ devel_api_focus_manager_header_files = \
 devel_api_image_loader_header_files = \
   $(devel_api_src_dir)/image-loader/async-image-loader-devel.h \
   $(devel_api_src_dir)/image-loader/atlas-upload-observer.h \
-  $(devel_api_src_dir)/image-loader/image-atlas.h
+  $(devel_api_src_dir)/image-loader/image-atlas.h \
+  $(devel_api_src_dir)/image-loader/texture-manager.h
 
 devel_api_scripting_header_files = \
   $(devel_api_src_dir)/scripting/script.h \
index d5ea993..25273f1 100644 (file)
@@ -142,6 +142,7 @@ DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "hiddenInputSettings",
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "pixelSize",                      FLOAT,     PIXEL_SIZE                           )
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "enableSelection",                BOOLEAN,   ENABLE_SELECTION                     )
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "placeholder",                    MAP,       PLACEHOLDER                          )
+DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "ellipsis",                       BOOLEAN,   ELLIPSIS                             )
 
 DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "textChanged",        SIGNAL_TEXT_CHANGED )
 DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "maxLengthReached",   SIGNAL_MAX_LENGTH_REACHED )
@@ -772,6 +773,17 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
         }
         break;
       }
+      case Toolkit::DevelTextField::Property::ELLIPSIS:
+      {
+        if( impl.mController )
+        {
+          const bool ellipsis = value.Get<bool>();
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p ELLIPSIS %d\n", impl.mController.Get(), ellipsis );
+
+          impl.mController->SetTextElideEnabled( ellipsis );
+        }
+        break;
+      }
     } // switch
   } // textfield
 }
@@ -1165,6 +1177,14 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
         value = map;
         break;
       }
+      case Toolkit::DevelTextField::Property::ELLIPSIS:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->IsTextElideEnabled();
+        }
+        break;
+      }
     } //switch
   }
 
index b524710..c7d92c2 100755 (executable)
@@ -181,6 +181,9 @@ void TypesetGlyph( GlyphData& data,
   }
   else
   {
+    // Whether the given glyph is a color one.
+    const bool isColorGlyph = Pixel::BGRA8888 == data.glyphBitmap.format;
+
     // Initial vertical offset.
     const int yOffset = data.verticalOffset + position->y;
 
@@ -208,21 +211,24 @@ void TypesetGlyph( GlyphData& data,
 
         uint8_t* bitmapBuffer = reinterpret_cast< uint8_t* >( data.bitmapBuffer.GetBuffer() );
 
-        // Update the alpha channel.
-        const uint8_t alpha = *( data.glyphBitmap.buffer + glyphBufferOffset + index );
-
-        // Copy non-transparent pixels only
-        if ( alpha > 0u )
+        if ( !isColorGlyph )
         {
-          // Check alpha of overlapped pixels
-          uint8_t& currentAlpha = *( bitmapBuffer + verticalOffset + xOffsetIndex );
-          uint8_t newAlpha = static_cast<uint8_t>( color->a * static_cast<float>( alpha ) );
-
-          // For any pixel overlapped with the pixel in previous glyphs, make sure we don't
-          // overwrite a previous bigger alpha with a smaller alpha (in order to avoid
-          // semi-transparent gaps between joint glyphs with overlapped pixels, which could
-          // happen, for example, in the RTL text when we copy glyphs from right to left).
-          *( bitmapBuffer + verticalOffset + xOffsetIndex ) = std::max( currentAlpha, newAlpha );
+          // Update the alpha channel.
+          const uint8_t alpha = *( data.glyphBitmap.buffer + glyphBufferOffset + index );
+
+          // Copy non-transparent pixels only
+          if ( alpha > 0u )
+          {
+            // Check alpha of overlapped pixels
+            uint8_t& currentAlpha = *( bitmapBuffer + verticalOffset + xOffsetIndex );
+            uint8_t newAlpha = static_cast<uint8_t>( color->a * static_cast<float>( alpha ) );
+
+            // For any pixel overlapped with the pixel in previous glyphs, make sure we don't
+            // overwrite a previous bigger alpha with a smaller alpha (in order to avoid
+            // semi-transparent gaps between joint glyphs with overlapped pixels, which could
+            // happen, for example, in the RTL text when we copy glyphs from right to left).
+            *( bitmapBuffer + verticalOffset + xOffsetIndex ) = std::max( currentAlpha, newAlpha );
+          }
         }
       }
     }
index fef0f70..0101616 100644 (file)
@@ -106,7 +106,9 @@ EventData::EventData( DecoratorPtr decorator )
   mAllTextSelected( false ),
   mUpdateInputStyle( false ),
   mPasswordInput( false ),
-  mIsPlaceholderPixelSize( false )
+  mIsPlaceholderPixelSize( false ),
+  mIsPlaceholderElideEnabled( false ),
+  mPlaceholderEllipsisFlag( false )
 {
   mImfManager = ImfManager::Get();
 }
index 898e2c6..23188f5 100644 (file)
@@ -159,6 +159,8 @@ struct EventData
   bool mPasswordInput                   : 1;   ///< True if password input is enabled.
   bool mCheckScrollAmount               : 1;   ///< Whether to check scrolled amount after updating the position
   bool mIsPlaceholderPixelSize          : 1;   ///< True if the placeholder font size is set as pixel size.
+  bool mIsPlaceholderElideEnabled       : 1;   ///< True if the placeholder text's elide is enabled.
+  bool mPlaceholderEllipsisFlag         : 1;   ///< True if the text controller sets the placeholder ellipsis.
 };
 
 struct ModifyEvent
index 482cfc3..4cc9d90 100755 (executable)
@@ -54,6 +54,7 @@ const char * const PLACEHOLDER_FONT_FAMILY = "placeholderFontFamily";
 const char * const PLACEHOLDER_FONT_STYLE = "placeholderFontStyle";
 const char * const PLACEHOLDER_POINT_SIZE = "placeholderPointSize";
 const char * const PLACEHOLDER_PIXEL_SIZE = "placeholderPixelSize";
+const char * const PLACEHOLDER_ELLIPSIS = "placeholderEllipsis";
 
 float ConvertToEven( float value )
 {
@@ -430,6 +431,24 @@ bool Controller::IsTextElideEnabled() const
   return mImpl->mModel->mElideEnabled;
 }
 
+void Controller::SetPlaceholderTextElideEnabled( bool enabled )
+{
+  mImpl->mEventData->mIsPlaceholderElideEnabled = enabled;
+  mImpl->mEventData->mPlaceholderEllipsisFlag = true;
+
+  // Update placeholder if there is no text
+  if( mImpl->IsShowingPlaceholderText() ||
+      ( 0u == mImpl->mModel->mLogicalModel->mText.Count() ) )
+  {
+    ShowPlaceholderText();
+  }
+}
+
+bool Controller::IsPlaceholderTextElideEnabled() const
+{
+  return mImpl->mEventData->mIsPlaceholderElideEnabled;
+}
+
 void Controller::SetSelectionEnabled( bool enabled )
 {
   mImpl->mEventData->mSelectionEnabled = enabled;
@@ -2006,6 +2025,12 @@ void Controller::SetPlaceholderProperty( const Property::Map& map )
         SetPlaceholderTextFontSize( pixelSize, Text::Controller::PIXEL_SIZE );
       }
     }
+    else if( key == PLACEHOLDER_ELLIPSIS )
+    {
+      bool ellipsis;
+      value.Get( ellipsis );
+      SetPlaceholderTextElideEnabled( ellipsis );
+    }
   }
 }
 
@@ -2038,6 +2063,11 @@ void Controller::GetPlaceholderProperty( Property::Map& map )
     {
       map[ PLACEHOLDER_PIXEL_SIZE ] = GetPlaceholderTextFontSize( Text::Controller::PIXEL_SIZE );
     }
+
+    if( mImpl->mEventData->mPlaceholderEllipsisFlag )
+    {
+      map[ PLACEHOLDER_ELLIPSIS ] = IsPlaceholderTextElideEnabled();
+    }
   }
 }
 
@@ -2095,6 +2125,20 @@ Controller::UpdateTextType Controller::Relayout( const Size& size )
                                                              COLOR );
   }
 
+  // Set the update info to elide the text.
+  if( mImpl->mModel->mElideEnabled ||
+      ( ( NULL != mImpl->mEventData ) && mImpl->mEventData->mIsPlaceholderElideEnabled ) )
+  {
+    // Update Text layout for applying elided
+    mImpl->mOperationsPending = static_cast<OperationsMask>( mImpl->mOperationsPending |
+                                                             ALIGN                     |
+                                                             LAYOUT                    |
+                                                             UPDATE_LAYOUT_SIZE        |
+                                                             REORDER );
+    mImpl->mTextUpdateInfo.mFullRelayoutNeeded = true;
+    mImpl->mTextUpdateInfo.mCharacterIndex = 0u;
+  }
+
   // Make sure the model is up-to-date before layouting.
   ProcessModifyEvents();
   bool updated = mImpl->UpdateModel( mImpl->mOperationsPending );
@@ -3279,13 +3323,35 @@ bool Controller::DoRelayout( const Size& size,
     layoutParameters.startLineIndex = mImpl->mTextUpdateInfo.mStartLineIndex;
     layoutParameters.estimatedNumberOfLines = mImpl->mTextUpdateInfo.mEstimatedNumberOfLines;
 
+    // Update the ellipsis
+    bool elideTextEnabled = mImpl->mModel->mElideEnabled;
+
+    if( NULL != mImpl->mEventData )
+    {
+      if( mImpl->mEventData->mPlaceholderEllipsisFlag && mImpl->IsShowingPlaceholderText() )
+      {
+        elideTextEnabled = mImpl->mEventData->mIsPlaceholderElideEnabled;
+      }
+      else if( EventData::INACTIVE != mImpl->mEventData->mState )
+      {
+        // Disable ellipsis when editing
+        elideTextEnabled = false;
+      }
+
+      // Reset the scroll position in inactive state
+      if( elideTextEnabled && ( mImpl->mEventData->mState == EventData::INACTIVE ) )
+      {
+        ResetScrollPosition();
+      }
+    }
+
     // Update the visual model.
     Size newLayoutSize;
     viewUpdated = mImpl->mLayoutEngine.LayoutText( layoutParameters,
                                                    glyphPositions,
                                                    mImpl->mModel->mVisualModel->mLines,
                                                    newLayoutSize,
-                                                   mImpl->mModel->mElideEnabled );
+                                                   elideTextEnabled );
 
     viewUpdated = viewUpdated || ( newLayoutSize != layoutSize );
 
index 3d0eb6c..b02bb68 100755 (executable)
@@ -369,6 +369,18 @@ public: // Configure the text controller.
   bool IsTextElideEnabled() const;
 
   /**
+   * @brief Enable or disable the placeholder text elide.
+   * @param enabled Whether to enable the placeholder text elide.
+   */
+  void SetPlaceholderTextElideEnabled( bool enabled );
+
+  /**
+   * @brief Whether the placeholder text elide property is enabled.
+   * @return True if the placeholder text elide property is enabled, false otherwise.
+   */
+  bool IsPlaceholderTextElideEnabled() const;
+
+  /**
    * @brief Enable or disable the text selection.
    * @param[in] enabled Whether to enable the text selection.
    */
index 9f775a1..acaede8 100644 (file)
@@ -274,6 +274,7 @@ void AnimatedImageVisual::DoSetProperty( Property::Index index,
       {
         mWrapModeU = Dali::WrapMode::Type::DEFAULT;
       }
+      break;
     }
     case Toolkit::ImageVisual::Property::WRAP_MODE_V:
     {
index ee0042a..5dbd3cd 100644 (file)
@@ -258,11 +258,10 @@ ImageVisual::ImageVisual( VisualFactoryCache& factoryCache,
                           Dali::SamplingMode::Type samplingMode )
 : Visual::Base( factoryCache ),
   mImage(),
-  mPixels(),
   mPixelArea( FULL_TEXTURE_RECT ),
   mPlacementActor(),
   mImageUrl( imageUrl ),
-  mMaskingData( NULL ),
+  mMaskingData( ),
   mDesiredSize( size ),
   mTextureId( TextureManager::INVALID_TEXTURE_ID ),
   mFittingMode( fittingMode ),
@@ -270,18 +269,17 @@ ImageVisual::ImageVisual( VisualFactoryCache& factoryCache,
   mWrapModeU( WrapMode::DEFAULT ),
   mWrapModeV( WrapMode::DEFAULT ),
   mAttemptAtlasing( false ),
-  mTextureLoading( false )
+  mLoadingStatus( false )
 {
 }
 
 ImageVisual::ImageVisual( VisualFactoryCache& factoryCache, const Image& image )
 : Visual::Base( factoryCache ),
   mImage( image ),
-  mPixels(),
   mPixelArea( FULL_TEXTURE_RECT ),
   mPlacementActor(),
   mImageUrl(),
-  mMaskingData( NULL ),
+  mMaskingData( ),
   mDesiredSize(),
   mTextureId( TextureManager::INVALID_TEXTURE_ID ),
   mFittingMode( FittingMode::DEFAULT ),
@@ -289,13 +287,23 @@ ImageVisual::ImageVisual( VisualFactoryCache& factoryCache, const Image& image )
   mWrapModeU( WrapMode::DEFAULT ),
   mWrapModeV( WrapMode::DEFAULT ),
   mAttemptAtlasing( false ),
-  mTextureLoading( false )
+  mLoadingStatus( false )
 {
 }
 
 ImageVisual::~ImageVisual()
 {
-  delete mMaskingData;
+  if( mMaskingData && Stage::IsInstalled() )
+  {
+    // TextureManager could have been deleted before the actor that contains this
+    // ImageVisual is destroyed (e.g. due to stage shutdown). Ensure the stage
+    // is still valid before accessing texture manager.
+    if( mMaskingData->mAlphaMaskId != TextureManager::INVALID_TEXTURE_ID )
+    {
+      TextureManager& textureManager = mFactoryCache.GetTextureManager();
+      textureManager.Remove( mMaskingData->mAlphaMaskId );
+    }
+  }
 }
 
 void ImageVisual::DoSetProperties( const Property::Map& propertyMap )
@@ -360,15 +368,6 @@ void ImageVisual::DoSetProperties( const Property::Map& propertyMap )
       }
     }
   }
-
-  if( ( mImpl->mFlags & Impl::IS_SYNCHRONOUS_RESOURCE_LOADING ) && mImageUrl.IsValid() )
-  {
-    // if sync loading is required, the loading should start
-    // immediately when new image url is set or the actor is off stage
-    // ( for on-stage actor with image url unchanged, resource loading
-    // is already finished )
-    LoadResourceSynchronously();
-  }
 }
 
 void ImageVisual::DoSetProperty( Property::Index index, const Property::Value& value )
@@ -476,7 +475,9 @@ void ImageVisual::DoSetProperty( Property::Index index, const Property::Value& v
       {
         AllocateMaskData();
         // Immediately trigger the alpha mask loading (it may just get a cached value)
-        mMaskingData->SetImage( alphaUrl );
+        mMaskingData->mAlphaMaskUrl = alphaUrl;
+        TextureManager& textureManager = mFactoryCache.GetTextureManager();
+        mMaskingData->mAlphaMaskId = textureManager.RequestMaskLoad( alphaUrl );
       }
       break;
     }
@@ -507,10 +508,9 @@ void ImageVisual::DoSetProperty( Property::Index index, const Property::Value& v
 
 void ImageVisual::AllocateMaskData()
 {
-  if( mMaskingData == NULL )
+  if( !mMaskingData )
   {
-    TextureManager& textureManager = mFactoryCache.GetTextureManager();
-    mMaskingData = new MaskingData(textureManager);
+    mMaskingData.reset(new TextureManager::MaskingData());
   }
 }
 
@@ -685,122 +685,42 @@ bool ImageVisual::IsSynchronousResourceLoading() const
   return mImpl->mFlags & Impl::IS_SYNCHRONOUS_RESOURCE_LOADING;
 }
 
-void ImageVisual::LoadResourceSynchronously()
-{
-  if( mImageUrl.IsValid() )
-  {
-    Devel::PixelBuffer pixelBuffer = LoadImageFromFile( mImageUrl.GetUrl(), mDesiredSize, mFittingMode, mSamplingMode );
-
-    if( pixelBuffer )
-    {
-      mPixels = Devel::PixelBuffer::Convert(pixelBuffer); // takes ownership of buffer
-    }
-    mTextureLoading = false;
-  }
-}
-
-TextureSet ImageVisual::CreateTextureSet( Vector4& textureRect, bool synchronousLoading, bool attemptAtlasing )
-{
-  TextureSet textureSet;
-
-  mTextureLoading = false;
-
-  textureRect = FULL_TEXTURE_RECT;
-  if( synchronousLoading )
-  {
-    if( !mPixels )
-    {
-      // use broken image
-      textureSet = TextureSet::New();
-      TextureSetImage( textureSet, 0u, VisualFactoryCache::GetBrokenVisualImage() );
-    }
-    else
-    {
-      if( attemptAtlasing )
-      {
-        textureSet = mFactoryCache.GetAtlasManager()->Add(textureRect, mPixels );
-        mImpl->mFlags |= Impl::IS_ATLASING_APPLIED;
-      }
-      if( !textureSet ) // big image, no atlasing or atlasing failed
-      {
-        mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED;
-        Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D, mPixels.GetPixelFormat(),
-                                        mPixels.GetWidth(), mPixels.GetHeight() );
-        texture.Upload( mPixels );
-        textureSet = TextureSet::New();
-        textureSet.SetTexture( 0u, texture );
-      }
-    }
-  }
-  else
-  {
-    if( attemptAtlasing )
-    {
-      textureSet = mFactoryCache.GetAtlasManager()->Add( textureRect, mImageUrl.GetUrl(), mDesiredSize, mFittingMode, true, this );
-      mImpl->mFlags |= Impl::IS_ATLASING_APPLIED;
-      mTextureLoading = true;
-    }
-    if( !textureSet ) // big image, no atlasing or atlasing failed
-    {
-      mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED;
-      TextureManager& textureManager = mFactoryCache.GetTextureManager();
-      if( mMaskingData == NULL )
-      {
-        mTextureId = textureManager.RequestLoad( mImageUrl, mDesiredSize, mFittingMode,
-                                                 mSamplingMode, TextureManager::NO_ATLAS, this );
-      }
-      else
-      {
-        mTextureId = textureManager.RequestLoad( mImageUrl,
-                                                 mMaskingData->mAlphaMaskId,
-                                                 mMaskingData->mContentScaleFactor,
-                                                 mDesiredSize,
-                                                 mFittingMode, mSamplingMode,
-                                                 TextureManager::NO_ATLAS,
-                                                 mMaskingData->mCropToMask,
-                                                 this );
-      }
-
-      TextureManager::LoadState loadState = textureManager.GetTextureState( mTextureId );
-
-      mTextureLoading = ( loadState == TextureManager::LOADING );
-
-      if( loadState == TextureManager::UPLOADED )
-      {
-        // UploadComplete has already been called - keep the same texture set
-        textureSet = textureManager.GetTextureSet(mTextureId);
-      }
-    }
-  }
-
-  if( ! (mImpl->mFlags & Impl::IS_ATLASING_APPLIED) && textureSet )
-  {
-    Sampler sampler = Sampler::New();
-    sampler.SetWrapMode(  mWrapModeU, mWrapModeV  );
-    textureSet.SetSampler( 0u, sampler );
-  }
-
-  return textureSet;
-}
-
+/*
+( VisualUrl& url, Dali::ImageDimensions desiredSize, Dali::FittingMode::Type fittingMode, Dali::SamplingMode::Type samplingMode,
+                                        ImageVisual::MaskingData* maskInfo, bool synchronousLoading,
+                                        TextureManager::TextureId textureId, Vector4& textureRect, bool& atlasingStatus, bool& loadingStatus
+ */
 void ImageVisual::InitializeRenderer()
 {
   mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED;
 
+  TextureManager& textureManager = mFactoryCache.GetTextureManager();
+
   if( ! mImpl->mCustomShader && mImageUrl.GetProtocolType() == VisualUrl::LOCAL )
   {
     bool defaultWrapMode = mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE;
 
     Vector4 atlasRect;
+
+    auto attemptAtlasing = mAttemptAtlasing;
+
     // texture set has to be created first as we need to know if atlasing succeeded or not
     // when selecting the shader
-    TextureSet textures = CreateTextureSet( atlasRect, IsSynchronousResourceLoading(), mAttemptAtlasing );
+    TextureSet textures =
+        textureManager.LoadTexture(mImageUrl, mDesiredSize, mFittingMode, mSamplingMode,
+                                   mMaskingData, IsSynchronousResourceLoading(), mTextureId,
+                                   atlasRect, attemptAtlasing, mLoadingStatus, mWrapModeU,
+                                   mWrapModeV, this, this, mFactoryCache.GetAtlasManager());
+    if(attemptAtlasing)
+    {
+      mImpl->mFlags |= Impl::IS_ATLASING_APPLIED;
+    }
     CreateRenderer( textures );
 
     if( mImpl->mFlags & Impl::IS_ATLASING_APPLIED ) // the texture is packed inside atlas
     {
       mImpl->mRenderer.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, atlasRect );
-      if( !defaultWrapMode ) // custom wrap mode, renderer is not cached.
+      if( !defaultWrapMode ) // custom wrap mode
       {
         Vector2 wrapMode(mWrapModeU-WrapMode::CLAMP_TO_EDGE, mWrapModeV-WrapMode::CLAMP_TO_EDGE);
         wrapMode.Clamp( Vector2::ZERO, Vector2( 2.f, 2.f ) );
@@ -810,16 +730,21 @@ void ImageVisual::InitializeRenderer()
   }
   else
   {
+    auto attemptAtlasing = false;
     // for custom shader or remote image, atlas is not applied
     Vector4 atlasRect; // ignored in this case
-    TextureSet textures = CreateTextureSet( atlasRect, IsSynchronousResourceLoading(), false );
+    TextureSet textures =
+        textureManager.LoadTexture(mImageUrl, mDesiredSize, mFittingMode, mSamplingMode,
+                                   mMaskingData, IsSynchronousResourceLoading(), mTextureId,
+                                   atlasRect, attemptAtlasing, mLoadingStatus, mWrapModeU, mWrapModeV, this,
+                                   nullptr, nullptr); // no atlasing
+    DALI_ASSERT_DEBUG(attemptAtlasing == false);
     CreateRenderer( textures );
   }
 }
 
 void ImageVisual::InitializeRenderer( const Image& image )
 {
-  // don't reuse CreateTextureSet
   TextureSet textures = TextureSet::New();
 
   NativeImage nativeImage = NativeImage::DownCast( image );
@@ -867,7 +792,7 @@ void ImageVisual::DoSetOnStage( Actor& actor )
     mImpl->mRenderer.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, mPixelArea );
   }
 
-  if( mTextureLoading == false )
+  if( mLoadingStatus == false )
   {
     actor.AddRenderer( mImpl->mRenderer );
     mPlacementActor.Reset();
@@ -888,7 +813,7 @@ void ImageVisual::DoSetOffStage( Actor& actor )
     RemoveTexture( mImageUrl.GetUrl() );
     mImage.Reset();
   }
-  mTextureLoading = false;
+  mLoadingStatus = false;
   mImpl->mRenderer.Reset();
   mPlacementActor.Reset();
 }
@@ -1024,7 +949,7 @@ void ImageVisual::UploadCompleted()
     // reset the weak handle so that the renderer only get added to actor once
     mPlacementActor.Reset();
   }
-  mTextureLoading = false;
+  mLoadingStatus = false;
 }
 
 // From Texture Manager
@@ -1059,7 +984,7 @@ void ImageVisual::UploadComplete( bool loadingSuccess, int32_t textureId, Textur
       ResourceReady();
     }
   }
-  mTextureLoading = false;
+  mLoadingStatus = false;
 }
 
 void ImageVisual::RemoveTexture(const std::string& url)
@@ -1089,36 +1014,6 @@ void ImageVisual::RemoveTexture(const std::string& url)
   }
 }
 
-
-ImageVisual::MaskingData::MaskingData( TextureManager& textureManager )
-: mTextureManager( textureManager ),
-  mAlphaMaskUrl(),
-  mAlphaMaskId( TextureManager::INVALID_TEXTURE_ID ),
-  mContentScaleFactor( 1.0f ),
-  mCropToMask( true )
-{
-}
-
-ImageVisual::MaskingData::~MaskingData()
-{
-  if( Stage::IsInstalled() )
-  {
-    // TextureManager could have been deleted before the actor that contains this
-    // ImageVisual is destroyed (e.g. due to stage shutdown). Ensure the stage
-    // is still valid before accessing texture manager.
-    if( mAlphaMaskId != TextureManager::INVALID_TEXTURE_ID )
-    {
-      mTextureManager.Remove( mAlphaMaskId );
-    }
-  }
-}
-
-void ImageVisual::MaskingData::SetImage( const std::string& maskUrl )
-{
-  mAlphaMaskUrl = maskUrl;
-  mAlphaMaskId = mTextureManager.RequestMaskLoad( mAlphaMaskUrl );
-}
-
 } // namespace Internal
 
 } // namespace Toolkit
index 334406f..a95753c 100644 (file)
@@ -19,6 +19,8 @@
  */
 
 // EXTERNAL INCLUDES
+#include <memory>
+
 #include <dali/public-api/common/intrusive-ptr.h>
 #include <dali/public-api/images/image.h>
 #include <dali/public-api/images/image-operations.h>
@@ -286,11 +288,6 @@ private:
   bool IsSynchronousResourceLoading() const;
 
   /**
-   * @brief Load the resource synchronously
-   */
-  void LoadResourceSynchronously();
-
-  /**
    * Creates the texture set and adds the texture to it
    * @param[out] textureRect The texture area of the texture in the atlas.
    * @param[in] url The URL of the image resource to use.
@@ -319,25 +316,12 @@ private:
   void DoSetProperty( Property::Index index, const Property::Value& value );
 
 private:
-  struct MaskingData
-  {
-    MaskingData( TextureManager& textureManager );
-    ~MaskingData();
-    void SetImage( const std::string& url );
-
-    TextureManager& mTextureManager;
-    VisualUrl mAlphaMaskUrl;
-    TextureManager::TextureId mAlphaMaskId;
-    float mContentScaleFactor;
-    bool mCropToMask;
-  };
 
   Image mImage;
-  PixelData mPixels;
   Vector4 mPixelArea;
   WeakHandle<Actor> mPlacementActor;
   VisualUrl mImageUrl;
-  MaskingData* mMaskingData;
+  TextureManager::MaskingDataPointer mMaskingData;
 
   Dali::ImageDimensions mDesiredSize;
   TextureManager::TextureId mTextureId;
@@ -346,8 +330,8 @@ private:
   Dali::SamplingMode::Type mSamplingMode:4;
   Dali::WrapMode::Type mWrapModeU:3;
   Dali::WrapMode::Type mWrapModeV:3;
-  bool mAttemptAtlasing:1; ///< If true will attempt atlasing, otherwise create unique texture
-  bool mTextureLoading:1;  ///< True if the texture is being loaded asynchronously, or false when it has loaded.
+  bool mAttemptAtlasing; ///< If true will attempt atlasing, otherwise create unique texture
+  bool mLoadingStatus;  ///< True if the texture is being loaded asynchronously, or false when it has loaded.
 };
 
 
index 4031f94..f274321 100755 (executable)
@@ -139,12 +139,46 @@ const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
   }\n
 );
 
-const char* FRAGMENT_SHADER_ATLAS_CLAMP_RGBA = DALI_COMPOSE_SHADER(
+const char* FRAGMENT_SHADER_SINGLE_COLOR_TEXT = DALI_COMPOSE_SHADER(
+  varying mediump vec2 vTexCoord;\n
+  uniform sampler2D sTexture;\n
+  uniform lowp vec4 uTextColorAnimatable;\n
+  uniform mediump vec4 uAtlasRect;\n
+  uniform lowp vec4 uColor;\n
+  uniform lowp vec3 mixColor;\n
+  uniform lowp float opacity;\n
+  \n
+  void main()\n
+  {\n
+    mediump vec2 texCoord = clamp( mix( uAtlasRect.xy, uAtlasRect.zw, vTexCoord ), uAtlasRect.xy, uAtlasRect.zw );\n
+    mediump float textTexture = texture2D( sTexture, texCoord ).r;\n
+
+    // Set the color of the text to what it is animated to.
+    gl_FragColor = uTextColorAnimatable * textTexture * uColor * vec4( mixColor, opacity );
+  }\n
+);
+
+const char* FRAGMENT_SHADER_MULTI_COLOR_TEXT = DALI_COMPOSE_SHADER(
+  varying mediump vec2 vTexCoord;\n
+  uniform sampler2D sTexture;\n
+  uniform mediump vec4 uAtlasRect;\n
+  uniform lowp vec4 uColor;\n
+  uniform lowp vec3 mixColor;\n
+  uniform lowp float opacity;\n
+  \n
+  void main()\n
+  {\n
+    mediump vec2 texCoord = clamp( mix( uAtlasRect.xy, uAtlasRect.zw, vTexCoord ), uAtlasRect.xy, uAtlasRect.zw );\n
+    mediump vec4 textTexture = texture2D( sTexture, texCoord );\n
+
+    gl_FragColor = textTexture * uColor * vec4( mixColor, opacity );
+  }\n
+);
+
+const char* FRAGMENT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE = DALI_COMPOSE_SHADER(
   varying mediump vec2 vTexCoord;\n
   uniform sampler2D sTexture;\n
   uniform sampler2D sStyle;\n
-  uniform sampler2D sMask;\n
-  uniform lowp float uHasMultipleTextColors;\n
   uniform lowp vec4 uTextColorAnimatable;\n
   uniform mediump vec4 uAtlasRect;\n
   uniform lowp vec4 uColor;\n
@@ -154,25 +188,68 @@ const char* FRAGMENT_SHADER_ATLAS_CLAMP_RGBA = DALI_COMPOSE_SHADER(
   void main()\n
   {\n
     mediump vec2 texCoord = clamp( mix( uAtlasRect.xy, uAtlasRect.zw, vTexCoord ), uAtlasRect.xy, uAtlasRect.zw );\n
+    mediump float textTexture = texture2D( sTexture, texCoord ).r;\n
+    mediump vec4 styleTexture = texture2D( sStyle, texCoord );\n
+
+    // Draw the text as overlay above the style
+    gl_FragColor = ( uTextColorAnimatable * textTexture + styleTexture * ( 1.0 - textTexture ) ) * uColor * vec4( mixColor, opacity );\n
+  }\n
+);
+
+const char* FRAGMENT_SHADER_MULTI_COLOR_TEXT_WITH_STYLE = DALI_COMPOSE_SHADER(
+  varying mediump vec2 vTexCoord;\n
+  uniform sampler2D sTexture;\n
+  uniform sampler2D sStyle;\n
+  uniform mediump vec4 uAtlasRect;\n
+  uniform lowp vec4 uColor;\n
+  uniform lowp vec3 mixColor;\n
+  uniform lowp float opacity;\n
+  \n
+  void main()\n
+  {\n
+    mediump vec2 texCoord = clamp( mix( uAtlasRect.xy, uAtlasRect.zw, vTexCoord ), uAtlasRect.xy, uAtlasRect.zw );\n
     mediump vec4 textTexture = texture2D( sTexture, texCoord );\n
     mediump vec4 styleTexture = texture2D( sStyle, texCoord );\n
-    mediump vec4 maskTexture = texture2D( sMask, texCoord );\n
+
+    // Draw the text as overlay above the style
+    gl_FragColor = ( textTexture + styleTexture * ( 1.0 - textTexture.a ) ) * uColor * vec4( mixColor, opacity );\n
+  }\n
+);
+
+const char* FRAGMENT_SHADER_SINGLE_COLOR_TEXT_WITH_EMOJI = DALI_COMPOSE_SHADER(
+  varying mediump vec2 vTexCoord;\n
+  uniform sampler2D sTexture;\n
+  uniform sampler2D sMask;\n
+  uniform lowp vec4 uTextColorAnimatable;\n
+  uniform mediump vec4 uAtlasRect;\n
+  uniform lowp vec4 uColor;\n
+  uniform lowp vec3 mixColor;\n
+  uniform lowp float opacity;\n
+  \n
+  void main()\n
+  {\n
+    mediump vec2 texCoord = clamp( mix( uAtlasRect.xy, uAtlasRect.zw, vTexCoord ), uAtlasRect.xy, uAtlasRect.zw );\n
+    mediump vec4 textTexture = texture2D( sTexture, texCoord );\n
+    mediump float maskTexture = texture2D( sMask, texCoord ).r;\n
 
     // Set the color of non-transparent pixel in text to what it is animated to.
     // Markup text with multiple text colors are not animated (but can be supported later on if required).
     // Emoji color are not animated.
     mediump vec4 textColor = textTexture * textTexture.a;\n
     mediump float vstep = step( 0.0001, textColor.a );\n
-    textColor.rgb = mix( textColor.rgb, uTextColorAnimatable.rgb, vstep * maskTexture.a * ( 1.0 - uHasMultipleTextColors ) );\n
+    textColor.rgb = mix( textColor.rgb, uTextColorAnimatable.rgb, vstep * maskTexture );\n
 
     // Draw the text as overlay above the style
-    gl_FragColor = ( textColor + styleTexture * ( 1.0 - textTexture.a ) ) * uColor * vec4( mixColor, opacity );\n
+    gl_FragColor = textColor * uColor * vec4( mixColor, opacity );\n
   }\n
 );
 
-const char* FRAGMENT_SHADER_ATLAS_CLAMP_L8 = DALI_COMPOSE_SHADER(
+const char* FRAGMENT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE_AND_EMOJI = DALI_COMPOSE_SHADER(
   varying mediump vec2 vTexCoord;\n
   uniform sampler2D sTexture;\n
+  uniform sampler2D sStyle;\n
+  uniform sampler2D sMask;\n
+  uniform lowp float uHasMultipleTextColors;\n
   uniform lowp vec4 uTextColorAnimatable;\n
   uniform mediump vec4 uAtlasRect;\n
   uniform lowp vec4 uColor;\n
@@ -182,10 +259,19 @@ const char* FRAGMENT_SHADER_ATLAS_CLAMP_L8 = DALI_COMPOSE_SHADER(
   void main()\n
   {\n
     mediump vec2 texCoord = clamp( mix( uAtlasRect.xy, uAtlasRect.zw, vTexCoord ), uAtlasRect.xy, uAtlasRect.zw );\n
-    mediump float textTexture = texture2D( sTexture, texCoord ).r;\n
+    mediump vec4 textTexture = texture2D( sTexture, texCoord );\n
+    mediump vec4 styleTexture = texture2D( sStyle, texCoord );\n
+    mediump float maskTexture = texture2D( sMask, texCoord ).r;\n
 
-    // Set the color of the text to what it is animated to.
-    gl_FragColor = uTextColorAnimatable * textTexture * uColor * vec4( mixColor, opacity );\n
+    // Set the color of non-transparent pixel in text to what it is animated to.
+    // Markup text with multiple text colors are not animated (but can be supported later on if required).
+    // Emoji color are not animated.
+    mediump vec4 textColor = textTexture * textTexture.a;\n
+    mediump float vstep = step( 0.0001, textColor.a );\n
+    textColor.rgb = mix( textColor.rgb, uTextColorAnimatable.rgb, vstep * maskTexture * ( 1.0 - uHasMultipleTextColors ) );\n
+
+    // Draw the text as overlay above the style
+    gl_FragColor = ( textColor + styleTexture * ( 1.0 - textTexture.a ) ) * uColor * vec4( mixColor, opacity );\n
   }\n
 );
 
@@ -380,7 +466,7 @@ void TextVisual::DoSetOnStage( Actor& actor )
   mControl = actor;
 
   Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY );
-  Shader shader = GetTextShader(mFactoryCache, true);
+  Shader shader = GetTextShader(mFactoryCache, TextType::SINGLE_COLOR_TEXT, TextType::NO_EMOJI, TextType::NO_STYLES);
 
   mImpl->mRenderer = Renderer::New( geometry, shader );
   mImpl->mRenderer.SetProperty( Dali::Renderer::Property::DEPTH_INDEX, Toolkit::DepthIndex::CONTENT );
@@ -594,101 +680,16 @@ void TextVisual::UpdateRenderer()
         shadowEnabled = true;
       }
 
-      bool outlineWidthEnabled = false;
-      float outlineWidth = mController->GetTextModel()->GetOutlineWidth();
-      if ( outlineWidth > Math::MACHINE_EPSILON_1 )
-      {
-        outlineWidthEnabled = true;
-      }
-
       const bool underlineEnabled = mController->GetTextModel()->IsUnderlineEnabled();
+      const bool outlineEnabled = ( mController->GetTextModel()->GetOutlineWidth() > Math::MACHINE_EPSILON_1 );
 
-      if ( hasMultipleTextColors || containsEmoji || shadowEnabled || underlineEnabled || outlineWidthEnabled )
-      {
-        // Create RGBA textures if the text contains emojis or styles or multiple text colors
-
-        // Create a texture for the text without any styles
-        PixelData data = mTypesetter->Render( relayoutSize, Text::Typesetter::RENDER_NO_STYLES );
-
-        // It may happen the image atlas can't handle a pixel data it exceeds the maximum size.
-        // In that case, create a texture. TODO: should tile the text.
-
-        Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D,
-                                        data.GetPixelFormat(),
-                                        data.GetWidth(),
-                                        data.GetHeight() );
-
-        texture.Upload( data );
-
-        TextureSet textureSet = TextureSet::New();
-        textureSet.SetTexture( 0u, texture );
-
-        // Create a texture for all the text styles (without the text itself)
-        PixelData styleData = mTypesetter->Render( relayoutSize, Text::Typesetter::RENDER_NO_TEXT );
-
-        Texture styleTexture = Texture::New( Dali::TextureType::TEXTURE_2D,
-                                             styleData.GetPixelFormat(),
-                                             styleData.GetWidth(),
-                                             styleData.GetHeight() );
-
-        styleTexture.Upload( styleData );
-
-        textureSet.SetTexture( 1u, styleTexture );
-
-        // Create a texture as a mask to avoid color glyphs (e.g. emojis) to be affected by text color animation
-        PixelData maskData = mTypesetter->Render( relayoutSize, Text::Typesetter::RENDER_MASK );
-
-        Texture maskTexture = Texture::New( Dali::TextureType::TEXTURE_2D,
-                                            styleData.GetPixelFormat(),
-                                            styleData.GetWidth(),
-                                            styleData.GetHeight() );
-
-        maskTexture.Upload( maskData );
-
-        textureSet.SetTexture( 2u, maskTexture );
-
-        // Filter mode needs to be set to nearest to produce better quality while static.
-        Sampler sampler = Sampler::New();
-        sampler.SetFilterMode( FilterMode::LINEAR, FilterMode::LINEAR );
-        textureSet.SetSampler( 0u, sampler );
-        textureSet.SetSampler( 1u, sampler );
-        textureSet.SetSampler( 2u, sampler );
-
-        mImpl->mRenderer.SetTextures( textureSet );
+      const bool styleEnabled = ( shadowEnabled || underlineEnabled || outlineEnabled );
 
-        Shader shader = GetTextShader(mFactoryCache, true); // RGBA shader
-        mImpl->mRenderer.SetShader(shader);
-      }
-      else
-      {
-        // Create L8 texture if the text contains only single text color with no emoji and no style
-
-        // Create a texture for the text without any styles
-        PixelData data = mTypesetter->Render( relayoutSize, Text::Typesetter::RENDER_NO_STYLES, false, Pixel::L8 );
-
-        // It may happen the image atlas can't handle a pixel data it exceeds the maximum size.
-        // In that case, create a texture. TODO: should tile the text.
-
-        Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D,
-                                        data.GetPixelFormat(),
-                                        data.GetWidth(),
-                                        data.GetHeight() );
-
-        texture.Upload( data );
+      TextureSet textureSet = GetTextTexture( relayoutSize, hasMultipleTextColors, containsEmoji, styleEnabled );
+      mImpl->mRenderer.SetTextures( textureSet );
 
-        TextureSet textureSet = TextureSet::New();
-        textureSet.SetTexture( 0u, texture );
-
-        // Filter mode needs to be set to nearest to produce better quality while static.
-        Sampler sampler = Sampler::New();
-        sampler.SetFilterMode( FilterMode::NEAREST, FilterMode::NEAREST );
-        textureSet.SetSampler( 0u, sampler );
-
-        mImpl->mRenderer.SetTextures( textureSet );
-
-        Shader shader = GetTextShader(mFactoryCache, false); // L8 shader
-        mImpl->mRenderer.SetShader(shader);
-      }
+      Shader shader = GetTextShader( mFactoryCache, hasMultipleTextColors, containsEmoji, styleEnabled );
+      mImpl->mRenderer.SetShader(shader);
 
       mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED;
 
@@ -728,27 +729,140 @@ void TextVisual::RemoveTextureSet()
   }
 }
 
-Shader TextVisual::GetTextShader( VisualFactoryCache& factoryCache, bool isRgbaTexture )
+TextureSet TextVisual::GetTextTexture( const Vector2& size, bool hasMultipleTextColors, bool containsEmoji, bool styleEnabled )
+{
+  // Filter mode needs to be set to linear to produce better quality while scaling.
+  Sampler sampler = Sampler::New();
+  sampler.SetFilterMode( FilterMode::LINEAR, FilterMode::LINEAR );
+
+  TextureSet textureSet = TextureSet::New();
+
+  // Create RGBA texture if the text contains emojis or multiple text colors, otherwise L8 texture
+  Pixel::Format textPixelFormat = ( containsEmoji || hasMultipleTextColors ) ? Pixel::RGBA8888 : Pixel::L8;
+
+  // Create a texture for the text without any styles
+  PixelData data = mTypesetter->Render( size, Text::Typesetter::RENDER_NO_STYLES, false, textPixelFormat );
+
+  // It may happen the image atlas can't handle a pixel data it exceeds the maximum size.
+  // In that case, create a texture. TODO: should tile the text.
+
+  Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D,
+                                  data.GetPixelFormat(),
+                                  data.GetWidth(),
+                                  data.GetHeight() );
+
+  texture.Upload( data );
+
+  textureSet.SetTexture( 0u, texture );
+  textureSet.SetSampler( 0u, sampler );
+
+  if ( styleEnabled )
+  {
+    // Create RGBA texture for all the text styles (without the text itself)
+    PixelData styleData = mTypesetter->Render( size, Text::Typesetter::RENDER_NO_TEXT, false, Pixel::RGBA8888 );
+
+    Texture styleTexture = Texture::New( Dali::TextureType::TEXTURE_2D,
+                                         styleData.GetPixelFormat(),
+                                         styleData.GetWidth(),
+                                         styleData.GetHeight() );
+
+    styleTexture.Upload( styleData );
+
+    textureSet.SetTexture( 1u, styleTexture );
+    textureSet.SetSampler( 1u, sampler );
+  }
+
+  if ( containsEmoji && !hasMultipleTextColors )
+  {
+    // Create a L8 texture as a mask to avoid color glyphs (e.g. emojis) to be affected by text color animation
+    PixelData maskData = mTypesetter->Render( size, Text::Typesetter::RENDER_MASK, false, Pixel::L8 );
+
+    Texture maskTexture = Texture::New( Dali::TextureType::TEXTURE_2D,
+                                        maskData.GetPixelFormat(),
+                                        maskData.GetWidth(),
+                                        maskData.GetHeight() );
+
+    maskTexture.Upload( maskData );
+
+    if ( !styleEnabled )
+    {
+      textureSet.SetTexture( 1u, maskTexture );
+      textureSet.SetSampler( 1u, sampler );
+    }
+    else
+    {
+      textureSet.SetTexture( 2u, maskTexture );
+      textureSet.SetSampler( 2u, sampler );
+    }
+  }
+
+  return textureSet;
+}
+
+Shader TextVisual::GetTextShader( VisualFactoryCache& factoryCache, bool hasMultipleTextColors, bool containsEmoji, bool styleEnabled )
 {
   Shader shader;
-  if( isRgbaTexture )
+
+  if( hasMultipleTextColors && !styleEnabled )
+  {
+    // We don't animate text color if the text contains multiple colors
+    shader = factoryCache.GetShader( VisualFactoryCache::TEXT_SHADER_MULTI_COLOR_TEXT );
+    if( !shader )
+    {
+      shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_MULTI_COLOR_TEXT );
+      shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
+      factoryCache.SaveShader( VisualFactoryCache::TEXT_SHADER_MULTI_COLOR_TEXT, shader );
+    }
+  }
+  else if( hasMultipleTextColors && styleEnabled )
+  {
+    // We don't animate text color if the text contains multiple colors
+    shader = factoryCache.GetShader( VisualFactoryCache::TEXT_SHADER_MULTI_COLOR_TEXT_WITH_STYLE );
+    if( !shader )
+    {
+      shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_MULTI_COLOR_TEXT_WITH_STYLE );
+      shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
+      factoryCache.SaveShader( VisualFactoryCache::TEXT_SHADER_MULTI_COLOR_TEXT_WITH_STYLE, shader );
+    }
+  }
+  else if( !hasMultipleTextColors && !containsEmoji && !styleEnabled )
+  {
+    shader = factoryCache.GetShader( VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT );
+    if( !shader )
+    {
+      shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_SINGLE_COLOR_TEXT );
+      shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
+      factoryCache.SaveShader( VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT, shader );
+    }
+  }
+  else if( !hasMultipleTextColors && !containsEmoji && styleEnabled )
+  {
+    shader = factoryCache.GetShader( VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE );
+    if( !shader )
+    {
+      shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE );
+      shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
+      factoryCache.SaveShader( VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE, shader );
+    }
+  }
+  else if( !hasMultipleTextColors && containsEmoji && !styleEnabled )
   {
-    shader = factoryCache.GetShader( VisualFactoryCache::TEXT_SHADER_RGBA );
+    shader = factoryCache.GetShader( VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_EMOJI );
     if( !shader )
     {
-      shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_ATLAS_CLAMP_RGBA );
+      shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_SINGLE_COLOR_TEXT_WITH_EMOJI );
       shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
-      factoryCache.SaveShader( VisualFactoryCache::TEXT_SHADER_RGBA, shader );
+      factoryCache.SaveShader( VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_EMOJI, shader );
     }
   }
-  else
+  else // if( !hasMultipleTextColors && containsEmoji && styleEnabled )
   {
-    shader = factoryCache.GetShader( VisualFactoryCache::TEXT_SHADER_L8 );
+    shader = factoryCache.GetShader( VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE_AND_EMOJI );
     if( !shader )
     {
-      shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_ATLAS_CLAMP_L8 );
+      shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE_AND_EMOJI );
       shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
-      factoryCache.SaveShader( VisualFactoryCache::TEXT_SHADER_L8, shader );
+      factoryCache.SaveShader( VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE_AND_EMOJI, shader );
     }
   }
 
index 31353b9..e859cbf 100644 (file)
@@ -192,11 +192,22 @@ private:
   void RemoveTextureSet();
 
   /**
+   * Get the texture of the text for rendering.
+   * @param[in] size The texture size.
+   * @param[in] hasMultipleTextColors Whether the text contains multiple colors.
+   * @param[in] containsEmoji Whether the text contains emoji.
+   * @param[in] styleEnabled Whether the text contains any styles (e.g. shadow, underline, etc.).
+   */
+  TextureSet GetTextTexture( const Vector2& size, bool hasMultipleTextColors, bool containsEmoji, bool styleEnabled );
+
+  /**
    * Get the text rendering shader.
    * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
-   * @param[in] isRgbaTexture Whether the texture is in RGBA format.
+   * @param[in] hasMultipleTextColors Whether the text contains multiple colors.
+   * @param[in] containsEmoji Whether the text contains emoji.
+   * @param[in] styleEnabled Whether the text contains any styles (e.g. shadow, underline, etc.).
    */
-  Shader GetTextShader( VisualFactoryCache& factoryCache, bool isRgbaTexture );
+  Shader GetTextShader( VisualFactoryCache& factoryCache, bool hasMultipleTextColors, bool containsEmoji, bool styleEnabled );
 
   /**
    * @brief Retrieve the text's controller.
@@ -209,6 +220,24 @@ private:
   };
 
 private:
+
+  /**
+   * Used as an alternative to boolean so that it is obvious whether the text contains single or multiple text colors, and emoji and styles.
+   */
+  struct TextType
+  {
+    enum Type
+    {
+      SINGLE_COLOR_TEXT = 0, ///< The text contains single color only.
+      MULTI_COLOR_TEXT = 1,  ///< The text contains multiple colors.
+      NO_EMOJI = 0,          ///< The text contains no emoji.
+      HAS_EMOJI = 1,         ///< The text contains emoji.
+      NO_STYLES = 0,         ///< The text contains contains no styles.
+      HAS_SYLES = 1          ///< The text contains contains styles.
+    };
+  };
+
+private:
   Text::ControllerPtr mController;                        ///< The text's controller.
   Text::TypesetterPtr mTypesetter;                        ///< The text's typesetter.
   WeakHandle<Actor>   mControl;                           ///< The control where the renderer is added.
index f074087..66f6a81 100644 (file)
@@ -21,7 +21,9 @@
 // EXTERNAL HEADERS
 #include <cstdlib>
 #include <string>
+#include <dali/public-api/math/vector4.h>
 #include <dali/devel-api/adaptor-framework/environment-variable.h>
+#include <dali/devel-api/adaptor-framework/image-loading.h>
 #include <dali/devel-api/common/hash.h>
 #include <dali/devel-api/images/texture-set-image.h>
 #include <dali/devel-api/adaptor-framework/pixel-buffer.h>
@@ -30,6 +32,7 @@
 // INTERNAL HEADERS
 #include <dali-toolkit/internal/image-loader/image-atlas-impl.h>
 #include <dali-toolkit/public-api/image-loader/sync-image-loader.h>
+#include <dali-toolkit/internal/visuals/image-atlas-manager.h>
 
 namespace
 {
@@ -84,6 +87,13 @@ const int           INVALID_CACHE_INDEX( -1 ); ///< Invalid Cache index
 
 } // Anonymous namespace
 
+TextureManager::MaskingData::MaskingData()
+: mAlphaMaskUrl(),
+  mAlphaMaskId( INVALID_TEXTURE_ID ),
+  mContentScaleFactor( 1.0f ),
+  mCropToMask( true )
+{
+}
 
 TextureManager::TextureManager()
 : mAsyncLocalLoaders( GetNumberOfLocalLoaderThreads(), [&]() { return AsyncLoadingHelper(*this); } ),
@@ -92,6 +102,125 @@ TextureManager::TextureManager()
 {
 }
 
+TextureSet TextureManager::LoadTexture(
+    VisualUrl& url, Dali::ImageDimensions desiredSize, Dali::FittingMode::Type fittingMode,
+    Dali::SamplingMode::Type samplingMode, const MaskingDataPointer& maskInfo,
+    bool synchronousLoading, TextureManager::TextureId& textureId, Vector4& textureRect,
+    bool& atlasingStatus, bool& loadingStatus, Dali::WrapMode::Type wrapModeU,
+    Dali::WrapMode::Type wrapModeV, TextureUploadObserver* textureObserver,
+    AtlasUploadObserver* atlasObserver, ImageAtlasManagerPtr imageAtlasManager)
+{
+  TextureSet textureSet;
+
+  loadingStatus = false;
+  textureRect = FULL_ATLAS_RECT;
+
+  if( VisualUrl::TEXTURE == url.GetProtocolType())
+  {
+    std::string location = url.GetLocation();
+    if( location.size() > 0u )
+    {
+      TextureId id = std::stoi( location );
+      for( auto&& elem : mExternalTextures )
+      {
+        if( elem.textureId == id )
+        {
+          return elem.textureSet;
+        }
+      }
+    }
+  }
+  else if( synchronousLoading )
+  {
+    PixelData data;
+    if( url.IsValid() )
+    {
+      // if sync loading is required, the loading should immediately when actor is on stage
+      Devel::PixelBuffer pixelBuffer = LoadImageFromFile( url.GetUrl(), desiredSize, fittingMode, samplingMode );
+      if( pixelBuffer )
+      {
+        data = Devel::PixelBuffer::Convert(pixelBuffer); // takes ownership of buffer
+      }
+    }
+    if( !data )
+    {
+      // use broken image
+      textureSet = TextureSet::New();
+      Devel::PixelBuffer pixelBuffer = LoadImageFromFile( BROKEN_IMAGE_URL );
+      if( pixelBuffer )
+      {
+        data = Devel::PixelBuffer::Convert(pixelBuffer); // takes ownership of buffer
+      }
+      Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D, data.GetPixelFormat(),
+                                      data.GetWidth(), data.GetHeight() );
+      texture.Upload( data );
+      textureSet = TextureSet::New();
+      textureSet.SetTexture( 0u, texture );
+    }
+    else
+    {
+      if( atlasingStatus ) // attempt atlasing
+      {
+        textureSet = imageAtlasManager->Add( textureRect, data );
+      }
+      if( !textureSet ) // big image, no atlasing or atlasing failed
+      {
+        atlasingStatus = false;
+        Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D, data.GetPixelFormat(),
+                                        data.GetWidth(), data.GetHeight() );
+        texture.Upload( data );
+        textureSet = TextureSet::New();
+        textureSet.SetTexture( 0u, texture );
+      }
+    }
+  }
+  else
+  {
+    loadingStatus = true;
+    if( atlasingStatus )
+    {
+      textureSet = imageAtlasManager->Add( textureRect, url.GetUrl(), desiredSize, fittingMode, true, atlasObserver );
+    }
+    if( !textureSet ) // big image, no atlasing or atlasing failed
+    {
+      atlasingStatus = false;
+      if( !maskInfo )
+      {
+        textureId = RequestLoad( url, desiredSize, fittingMode, samplingMode, TextureManager::NO_ATLAS, textureObserver );
+      }
+      else
+      {
+        textureId = RequestLoad( url,
+                                 maskInfo->mAlphaMaskId,
+                                 maskInfo->mContentScaleFactor,
+                                 desiredSize,
+                                 fittingMode, samplingMode,
+                                 TextureManager::NO_ATLAS,
+                                 maskInfo->mCropToMask,
+                                 textureObserver );
+      }
+
+      TextureManager::LoadState loadState = GetTextureState( textureId );
+      loadingStatus = ( loadState == TextureManager::LOADING );
+
+      if( loadState == TextureManager::UPLOADED )
+      {
+        // UploadComplete has already been called - keep the same texture set
+        textureSet = GetTextureSet( textureId );
+      }
+    }
+  }
+
+  if( ! atlasingStatus && textureSet )
+  {
+    Sampler sampler = Sampler::New();
+    sampler.SetWrapMode(  wrapModeU, wrapModeV  );
+    textureSet.SetSampler( 0u, sampler );
+  }
+
+  return textureSet;
+}
+
 TextureManager::TextureId TextureManager::RequestLoad(
   const VisualUrl&         url,
   const ImageDimensions    desiredSize,
@@ -123,7 +252,6 @@ TextureManager::TextureId TextureManager::RequestMaskLoad( const VisualUrl& mask
   return RequestLoadInternal( maskUrl, INVALID_TEXTURE_ID, 1.0f, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::NO_FILTER, NO_ATLAS, false, KEEP_PIXEL_BUFFER, NULL );
 }
 
-
 TextureManager::TextureId TextureManager::RequestLoadInternal(
   const VisualUrl&         url,
   TextureId                maskTextureId,
@@ -715,10 +843,6 @@ void TextureManager::ObserverDestroyed( TextureUploadObserver* observer )
   }
 }
 
-TextureManager::~TextureManager()
-{
-}
-
 TextureManager::AsyncLoadingHelper::AsyncLoadingHelper(TextureManager& textureManager)
 : AsyncLoadingHelper(Toolkit::AsyncImageLoader::New(), textureManager,
                      AsyncLoadingInfoContainerType())
index 117bd1f..7a243fd 100644 (file)
@@ -21,6 +21,7 @@
 #include <deque>
 #include <functional>
 #include <string>
+#include <memory>
 #include <dali/public-api/common/dali-vector.h>
 #include <dali/public-api/object/ref-object.h>
 #include <dali/public-api/rendering/texture-set.h>
@@ -45,6 +46,8 @@ namespace Toolkit
 
 namespace Internal
 {
+class ImageAtlasManager;
+typedef IntrusivePtr<ImageAtlasManager> ImageAtlasManagerPtr;
 
 /**
  * The TextureManager provides a common Image loading API for Visuals.
@@ -103,6 +106,18 @@ public:
 
 public:
 
+  struct MaskingData
+  {
+    MaskingData();
+    ~MaskingData() = default;
+
+    VisualUrl mAlphaMaskUrl;
+    TextureManager::TextureId mAlphaMaskId;
+    float mContentScaleFactor;
+    bool mCropToMask;
+  };
+  using MaskingDataPointer = std::unique_ptr<MaskingData>;
+
   /**
    * Constructor.
    */
@@ -111,11 +126,20 @@ public:
   /**
    * Destructor.
    */
-  ~TextureManager();
+  ~TextureManager() = default;
 
 
   // TextureManager Main API:
 
+  TextureSet LoadTexture(VisualUrl& url, Dali::ImageDimensions desiredSize,
+                         Dali::FittingMode::Type fittingMode, Dali::SamplingMode::Type samplingMode,
+                         const MaskingDataPointer& maskInfo, bool synchronousLoading,
+                         TextureManager::TextureId& textureId, Vector4& textureRect,
+                         bool& atlasingStatus, bool& loadingStatus, Dali::WrapMode::Type wrapModeU,
+                         Dali::WrapMode::Type wrapModeV, TextureUploadObserver* textureObserver,
+                         AtlasUploadObserver* atlasObserver,
+                         ImageAtlasManagerPtr imageAtlasManager);
+
   /**
    * @brief Requests an image load of the given URL.
    *
@@ -345,25 +369,9 @@ private:
     unsigned short      loadId;      ///< The load Id used by the async loader to reference this load
   };
 
-  /**
-   * @brief This struct is used within a container to manage atlas creation and destruction.
-   */
-  struct AtlasInfo
-  {
-    AtlasInfo( Toolkit::ImageAtlas atlas, TextureSet textureSet )
-    : atlas( atlas ),
-      textureSet( textureSet )
-    {
-    }
-
-    Toolkit::ImageAtlas                 atlas;                          ///< The ImageAtlas object
-    TextureSet                          textureSet;                     ///< The TextureSet is kept in the struct to allow fast lookup of TextureSet to Atlas
-  };
-
   // Private typedefs:
 
   typedef std::deque<AsyncLoadingInfo>  AsyncLoadingInfoContainerType;  ///< The container type used to manage Asynchronous loads in progress
-  typedef std::vector<AtlasInfo>        AtlasInfoContainerType;         ///< The container type used to manage Atlas creation and destruction
   typedef std::vector<TextureInfo>      TextureInfoContainerType;       ///< The container type used to manage the life-cycle and caching of Textures
 
   /**
@@ -586,7 +594,6 @@ private:
 
 private:  // Member Variables:
 
-  AtlasInfoContainerType                        mAtlasContainer;       ///< Used to manage Atlas creation and destruction
   TextureInfoContainerType                      mTextureInfoContainer; ///< Used to manage the life-cycle and caching of Textures
   RoundRobinContainerView< AsyncLoadingHelper > mAsyncLocalLoaders;    ///< The Asynchronous image loaders used to provide all local async loads
   RoundRobinContainerView< AsyncLoadingHelper > mAsyncRemoteLoaders;   ///< The Asynchronous image loaders used to provide all remote async loads
index aac15c7..3e9f076 100644 (file)
@@ -69,8 +69,12 @@ public:
     IMAGE_SHADER_ATLAS_CUSTOM_WRAP,
     NINE_PATCH_SHADER,
     SVG_SHADER,
-    TEXT_SHADER_RGBA,
-    TEXT_SHADER_L8,
+    TEXT_SHADER_MULTI_COLOR_TEXT,
+    TEXT_SHADER_MULTI_COLOR_TEXT_WITH_STYLE,
+    TEXT_SHADER_SINGLE_COLOR_TEXT,
+    TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE,
+    TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_EMOJI,
+    TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE_AND_EMOJI,
     WIREFRAME_SHADER,
     SHADER_TYPE_MAX = WIREFRAME_SHADER
   };
index 1edcdb5..2201047 100644 (file)
@@ -31,7 +31,7 @@ namespace Toolkit
 
 const unsigned int TOOLKIT_MAJOR_VERSION = 1;
 const unsigned int TOOLKIT_MINOR_VERSION = 2;
-const unsigned int TOOLKIT_MICRO_VERSION = 58;
+const unsigned int TOOLKIT_MICRO_VERSION = 59;
 const char * const TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index 8b2bb60..75cb4a5 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali-toolkit
 Summary:    Dali 3D engine Toolkit
-Version:    1.2.58
+Version:    1.2.59
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT
@@ -295,22 +295,37 @@ popd
 ##############################
 
 %preun resources_480x800
-pushd %{dali_toolkit_style_files}
-mv images ./480x800
-mv dali-toolkit-default-theme.json ./480x800
-popd
+case "$1" in
+  0)
+    %preun resources_480x800
+    pushd %{dali_toolkit_style_files}
+    mv images ./480x800
+    mv dali-toolkit-default-theme.json ./480x800
+    popd
+  ;;
+esac
 
 %preun resources_720x1280
-pushd %{dali_toolkit_style_files}
-mv images ./720x1280
-mv dali-toolkit-default-theme.json ./720x1280
-popd
+case "$1" in
+  0)
+    %preun resources_720x1280
+    pushd %{dali_toolkit_style_files}
+    mv images ./720x1280
+    mv dali-toolkit-default-theme.json ./720x1280
+    popd
+  ;;
+esac
 
 %preun resources_1920x1080
-pushd %{dali_toolkit_style_files}
-mv images ./1920x1080
-mv dali-toolkit-default-theme.json ./1920x1080
-popd
+case "$1" in
+  0)
+    %preun resources_1920x1080
+    pushd %{dali_toolkit_style_files}
+    mv images ./1920x1080
+    mv dali-toolkit-default-theme.json ./1920x1080
+    popd
+  ;;
+esac
 
 ##############################
 # Post Uninstall