Revert TextVisual in TextLabel Patches 44/148744/3
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Fri, 8 Sep 2017 15:21:54 +0000 (16:21 +0100)
committerAdeel Kazmi <adeel.kazmi@samsung.com>
Fri, 8 Sep 2017 16:01:28 +0000 (17:01 +0100)
"Reduce text visual memory consumption for text with no styles and emojis"
"(TextLabel) Added component properties for Text Color"
"Fix issues while rendering RTL text in Text Visual"
"Fix the padding issue while text is scrolling in TextLabel"
"Change filter mode in TextLabel to improve quality while scaling"
"Refactor TextLabel to use text visual"

Change-Id: I4b75398f8381272d0ae30b556efb71eb8516c6b6

22 files changed:
automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp
dali-toolkit/devel-api/visuals/text-visual-properties.h
dali-toolkit/internal/controls/text-controls/text-label-impl.cpp
dali-toolkit/internal/controls/text-controls/text-label-impl.h
dali-toolkit/internal/text/rendering/text-typesetter.cpp
dali-toolkit/internal/text/rendering/text-typesetter.h
dali-toolkit/internal/text/rendering/view-model.cpp
dali-toolkit/internal/text/rendering/view-model.h
dali-toolkit/internal/text/text-controller.cpp
dali-toolkit/internal/text/text-controller.h
dali-toolkit/internal/text/text-model-interface.h
dali-toolkit/internal/text/text-model.cpp
dali-toolkit/internal/text/text-model.h
dali-toolkit/internal/text/text-scroller.cpp
dali-toolkit/internal/text/text-scroller.h
dali-toolkit/internal/text/text-view.cpp
dali-toolkit/internal/text/visual-model-impl.cpp
dali-toolkit/internal/text/visual-model-impl.h
dali-toolkit/internal/visuals/text/text-visual.cpp
dali-toolkit/internal/visuals/text/text-visual.h
dali-toolkit/internal/visuals/visual-factory-cache.h
dali-toolkit/public-api/controls/text-controls/text-label.h

index beba3a6..1a642dd 100644 (file)
@@ -986,7 +986,6 @@ int UtcDaliToolkitTextLabelColorComponents(void)
   label.SetProperty( DevelTextLabel::Property::TEXT_COLOR_ALPHA, 0.6f );
   DALI_TEST_EQUALS( label.GetProperty< float >( DevelTextLabel::Property::TEXT_COLOR_ALPHA ), 0.6f, TEST_LOCATION );
   DALI_TEST_EQUALS( label.GetProperty< Vector4 >( DevelTextLabel::Property::TEXT_COLOR_ANIMATABLE ), Vector4( 0.0f, 0.0f, 1.0f, 0.6f ), TEST_LOCATION );
   label.SetProperty( DevelTextLabel::Property::TEXT_COLOR_ALPHA, 0.6f );
   DALI_TEST_EQUALS( label.GetProperty< float >( DevelTextLabel::Property::TEXT_COLOR_ALPHA ), 0.6f, TEST_LOCATION );
   DALI_TEST_EQUALS( label.GetProperty< Vector4 >( DevelTextLabel::Property::TEXT_COLOR_ANIMATABLE ), Vector4( 0.0f, 0.0f, 1.0f, 0.6f ), TEST_LOCATION );
-  DALI_TEST_EQUALS( label.GetProperty< Vector4 >( TextLabel::Property::TEXT_COLOR ), Vector4( 0.0f, 0.0f, 1.0f, 0.6f ), TEST_LOCATION );
 
   END_TEST;
 }
 
   END_TEST;
 }
index 4286c38..10adcbc 100644 (file)
@@ -88,18 +88,6 @@ enum
    * @details name "enableMarkup", type BOOLEAN
    */
   ENABLE_MARKUP,
    * @details name "enableMarkup", type BOOLEAN
    */
   ENABLE_MARKUP,
-
-  /**
-   * @brief The shadow parameters.
-   * @details name "shadow", type MAP.
-   */
-  SHADOW,
-
-  /**
-   * @brief The default underline parameters.
-   * @details name "underline", type MAP.
-   */
-  UNDERLINE,
 };
 
 } // namespace Property
 };
 
 } // namespace Property
index e871db3..db99cc4 100644 (file)
 #include <dali-toolkit/internal/text/text-definitions.h>
 #include <dali-toolkit/internal/styling/style-manager-impl.h>
 
 #include <dali-toolkit/internal/text/text-definitions.h>
 #include <dali-toolkit/internal/styling/style-manager-impl.h>
 
-#include <dali-toolkit/devel-api/align-enums.h>
-#include <dali-toolkit/devel-api/controls/control-devel.h>
-#include <dali-toolkit/devel-api/visual-factory/visual-base.h>
-#include <dali-toolkit/devel-api/visuals/text-visual-properties.h>
-#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
-#include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
-
 using namespace Dali::Toolkit::Text;
 
 namespace Dali
 using namespace Dali::Toolkit::Text;
 
 namespace Dali
@@ -104,7 +97,7 @@ BaseHandle Create()
 // Setup properties, signals and actions using the type-registry.
 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TextLabel, Toolkit::Control, Create );
 
 // Setup properties, signals and actions using the type-registry.
 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TextLabel, Toolkit::Control, Create );
 
-DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "renderingBackend",          INTEGER, RENDERING_BACKEND      ) // Deprecated property
+DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "renderingBackend",          INTEGER, RENDERING_BACKEND      )
 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "text",                      STRING,  TEXT                   )
 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "fontFamily",                STRING,  FONT_FAMILY            )
 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "fontStyle",                 MAP,     FONT_STYLE             )
 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "text",                      STRING,  TEXT                   )
 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "fontFamily",                STRING,  FONT_FAMILY            )
 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "fontStyle",                 MAP,     FONT_STYLE             )
@@ -134,7 +127,7 @@ DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextLabel, "autoScrollLoopDelay", FLO
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextLabel, "autoScrollStopMode",  STRING,  AUTO_SCROLL_STOP_MODE  )
 DALI_DEVEL_PROPERTY_REGISTRATION_READ_ONLY( Toolkit, TextLabel, "lineCount", INTEGER, LINE_COUNT             )
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextLabel, "lineWrapMode",        STRING,  LINE_WRAP_MODE         )
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextLabel, "autoScrollStopMode",  STRING,  AUTO_SCROLL_STOP_MODE  )
 DALI_DEVEL_PROPERTY_REGISTRATION_READ_ONLY( Toolkit, TextLabel, "lineCount", INTEGER, LINE_COUNT             )
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextLabel, "lineWrapMode",        STRING,  LINE_WRAP_MODE         )
-DALI_DEVEL_ANIMATABLE_PROPERTY_REGISTRATION_WITH_DEFAULT( Toolkit, TextLabel, "textColorAnimatable", Color::BLACK, TEXT_COLOR_ANIMATABLE )
+DALI_DEVEL_ANIMATABLE_PROPERTY_REGISTRATION_WITH_DEFAULT( Toolkit, TextLabel, "textColorAnimatable", Color::WHITE, TEXT_COLOR_ANIMATABLE )
 DALI_DEVEL_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit, TextLabel, "textColorRed",   TEXT_COLOR_RED,   TEXT_COLOR_ANIMATABLE, 0)
 DALI_DEVEL_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit, TextLabel, "textColorGreen", TEXT_COLOR_GREEN, TEXT_COLOR_ANIMATABLE, 1)
 DALI_DEVEL_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit, TextLabel, "textColorBlue",  TEXT_COLOR_BLUE,  TEXT_COLOR_ANIMATABLE, 2)
 DALI_DEVEL_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit, TextLabel, "textColorRed",   TEXT_COLOR_RED,   TEXT_COLOR_ANIMATABLE, 0)
 DALI_DEVEL_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit, TextLabel, "textColorGreen", TEXT_COLOR_GREEN, TEXT_COLOR_ANIMATABLE, 1)
 DALI_DEVEL_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit, TextLabel, "textColorBlue",  TEXT_COLOR_BLUE,  TEXT_COLOR_ANIMATABLE, 2)
@@ -169,8 +162,6 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
     {
       case Toolkit::TextLabel::Property::RENDERING_BACKEND:
       {
     {
       case Toolkit::TextLabel::Property::RENDERING_BACKEND:
       {
-        DALI_LOG_WARNING("[%s] Using deprecated Property TextLabel::Property::RENDERING_BACKEND which is no longer supported and will be ignored\n", __FUNCTION__);
-
         int backend = value.Get< int >();
 
 #ifndef ENABLE_VECTOR_BASED_TEXT_RENDERING
         int backend = value.Get< int >();
 
 #ifndef ENABLE_VECTOR_BASED_TEXT_RENDERING
@@ -182,7 +173,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
         if( impl.mRenderingBackend != backend )
         {
           impl.mRenderingBackend = backend;
         if( impl.mRenderingBackend != backend )
         {
           impl.mRenderingBackend = backend;
-          impl.mTextUpdateNeeded = true;
+          impl.mRenderer.Reset();
 
           if( impl.mController )
           {
 
           if( impl.mController )
           {
@@ -271,8 +262,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
 
       case Toolkit::TextLabel::Property::TEXT_COLOR:
       {
 
       case Toolkit::TextLabel::Property::TEXT_COLOR:
       {
-        label.SetProperty( DevelTextLabel::Property::TEXT_COLOR_ANIMATABLE, value );
-        impl.mTextUpdateNeeded = true;
+        SetProperty( object, DevelTextLabel::Property::TEXT_COLOR_ANIMATABLE, value );
         break;
       }
 
         break;
       }
 
@@ -284,7 +274,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
           if ( impl.mController->GetShadowOffset() != shadowOffset )
           {
             impl.mController->SetShadowOffset( shadowOffset );
           if ( impl.mController->GetShadowOffset() != shadowOffset )
           {
             impl.mController->SetShadowOffset( shadowOffset );
-            impl.mTextUpdateNeeded = true;
+            impl.mRenderer.Reset();
           }
         }
         break;
           }
         }
         break;
@@ -297,7 +287,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
           if ( impl.mController->GetShadowColor() != shadowColor )
           {
             impl.mController->SetShadowColor( shadowColor );
           if ( impl.mController->GetShadowColor() != shadowColor )
           {
             impl.mController->SetShadowColor( shadowColor );
-            impl.mTextUpdateNeeded = true;
+            impl.mRenderer.Reset();
           }
         }
         break;
           }
         }
         break;
@@ -310,7 +300,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
           if ( impl.mController->GetUnderlineColor() != color )
           {
             impl.mController->SetUnderlineColor( color );
           if ( impl.mController->GetUnderlineColor() != color )
           {
             impl.mController->SetUnderlineColor( color );
-            impl.mTextUpdateNeeded = true;
+            impl.mRenderer.Reset();
           }
         }
         break;
           }
         }
         break;
@@ -323,7 +313,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
           if ( impl.mController->IsUnderlineEnabled() != enabled )
           {
             impl.mController->SetUnderlineEnabled( enabled );
           if ( impl.mController->IsUnderlineEnabled() != enabled )
           {
             impl.mController->SetUnderlineEnabled( enabled );
-            impl.mTextUpdateNeeded = true;
+            impl.mRenderer.Reset();
           }
         }
         break;
           }
         }
         break;
@@ -337,7 +327,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
           if( fabsf( impl.mController->GetUnderlineHeight() - height ) > Math::MACHINE_EPSILON_1000 )
           {
             impl.mController->SetUnderlineHeight( height );
           if( fabsf( impl.mController->GetUnderlineHeight() - height ) > Math::MACHINE_EPSILON_1000 )
           {
             impl.mController->SetUnderlineHeight( height );
-            impl.mTextUpdateNeeded = true;
+            impl.mRenderer.Reset();
           }
         }
         break;
           }
         }
         break;
@@ -435,7 +425,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
         {
           const float lineSpacing = value.Get<float>();
           impl.mController->SetDefaultLineSpacing( lineSpacing );
         {
           const float lineSpacing = value.Get<float>();
           impl.mController->SetDefaultLineSpacing( lineSpacing );
-          impl.mTextUpdateNeeded = true;
+          impl.mRenderer.Reset();
         }
         break;
       }
         }
         break;
       }
@@ -444,7 +434,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
         const bool update = SetUnderlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
         if( update )
         {
         const bool update = SetUnderlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
         if( update )
         {
-          impl.mTextUpdateNeeded = true;
+          impl.mRenderer.Reset();
         }
         break;
       }
         }
         break;
       }
@@ -453,7 +443,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
         const bool update = SetShadowProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
         if( update )
         {
         const bool update = SetShadowProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
         if( update )
         {
-          impl.mTextUpdateNeeded = true;
+          impl.mRenderer.Reset();
         }
         break;
       }
         }
         break;
       }
@@ -462,7 +452,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
         const bool update = SetEmbossProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
         if( update )
         {
         const bool update = SetEmbossProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
         if( update )
         {
-          impl.mTextUpdateNeeded = true;
+          impl.mRenderer.Reset();
         }
         break;
       }
         }
         break;
       }
@@ -471,7 +461,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
         const bool update = SetOutlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
         if( update )
         {
         const bool update = SetOutlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
         if( update )
         {
-          impl.mTextUpdateNeeded = true;
+          impl.mRenderer.Reset();
         }
         break;
       }
         }
         break;
       }
@@ -532,8 +522,6 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde
     {
       case Toolkit::TextLabel::Property::RENDERING_BACKEND:
       {
     {
       case Toolkit::TextLabel::Property::RENDERING_BACKEND:
       {
-        DALI_LOG_WARNING("[%s] Using deprecated Property TextLabel::Property::RENDERING_BACKEND which is no longer supported and will be ignored\n", __FUNCTION__);
-
         value = impl.mRenderingBackend;
         break;
       }
         value = impl.mRenderingBackend;
         break;
       }
@@ -606,7 +594,10 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde
       }
       case Toolkit::TextLabel::Property::TEXT_COLOR:
       {
       }
       case Toolkit::TextLabel::Property::TEXT_COLOR:
       {
-        value = label.GetProperty( Toolkit::DevelTextLabel::Property::TEXT_COLOR_ANIMATABLE );
+        if( impl.mController )
+        {
+          value = impl.mController->GetDefaultColor();
+        }
         break;
       }
       case Toolkit::TextLabel::Property::SHADOW_OFFSET:
         break;
       }
       case Toolkit::TextLabel::Property::SHADOW_OFFSET:
@@ -792,19 +783,11 @@ void TextLabel::OnInitialize()
 {
   Actor self = Self();
 
 {
   Actor self = Self();
 
-  Property::Map propertyMap;
-  propertyMap.Add( Toolkit::Visual::Property::TYPE, Toolkit::DevelVisual::TEXT );
+  mController = Text::Controller::New( this );
 
 
-  mVisual =  Toolkit::VisualFactory::Get().CreateVisual( propertyMap );
-  DevelControl::RegisterVisual( *this, Toolkit::TextLabel::Property::TEXT, mVisual  );
-
-  TextVisual::SetAnimatableTextColorProperty( mVisual, Toolkit::DevelTextLabel::Property::TEXT_COLOR_ANIMATABLE );
-
-  mController = TextVisual::GetController(mVisual);
-  if( mController )
-  {
-    mController->SetControlInterface(this);
-  }
+  // When using the vector-based rendering, the size of the GLyphs are different
+  TextAbstraction::GlyphType glyphType = (Text::RENDERING_VECTOR_BASED == mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
+  mController->SetGlyphType( glyphType );
 
   // Use height-for-width negotiation by default
   self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
 
   // Use height-for-width negotiation by default
   self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
@@ -815,6 +798,8 @@ void TextLabel::OnInitialize()
 
   Layout::Engine& engine = mController->GetLayoutEngine();
   engine.SetCursorWidth( 0u ); // Do not layout space for the cursor.
 
   Layout::Engine& engine = mController->GetLayoutEngine();
   engine.SetCursorWidth( 0u ); // Do not layout space for the cursor.
+
+  self.OnStageSignal().Connect( this, &TextLabel::OnStageConnect );
 }
 
 void TextLabel::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change )
 }
 
 void TextLabel::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change )
@@ -867,13 +852,14 @@ void TextLabel::OnPropertySet( Property::Index index, Property::Value propertyVa
 
   switch ( index )
   {
 
   switch ( index )
   {
+    case Toolkit::TextLabel::Property::TEXT_COLOR:
     case Toolkit::DevelTextLabel::Property::TEXT_COLOR_ANIMATABLE:
     {
       const Vector4& textColor = propertyValue.Get< Vector4 >();
       if( mController->GetDefaultColor() != textColor )
       {
          mController->SetDefaultColor( textColor );
     case Toolkit::DevelTextLabel::Property::TEXT_COLOR_ANIMATABLE:
     {
       const Vector4& textColor = propertyValue.Get< Vector4 >();
       if( mController->GetDefaultColor() != textColor )
       {
          mController->SetDefaultColor( textColor );
-         mTextUpdateNeeded = true;
+         mRenderer.Reset();
       }
       break;
     }
       }
       break;
     }
@@ -893,50 +879,76 @@ void TextLabel::OnRelayout( const Vector2& size, RelayoutContainer& container )
   Self().GetPadding( padding );
   Vector2 contentSize( size.x - ( padding.left + padding.right ), size.y - ( padding.top + padding.bottom ) );
 
   Self().GetPadding( padding );
   Vector2 contentSize( size.x - ( padding.left + padding.right ), size.y - ( padding.top + padding.bottom ) );
 
+
   const Text::Controller::UpdateTextType updateTextType = mController->Relayout( contentSize );
 
   const Text::Controller::UpdateTextType updateTextType = mController->Relayout( contentSize );
 
-  if( ( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType ) )
-     || mTextUpdateNeeded )
+  if( ( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType ) ) ||
+      !mRenderer )
   {
   {
-    DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::OnRelayout IsAutoScrollEnabled[%s] [%p]\n", ( mController->IsAutoScrollEnabled())?"true":"false", this );
+    if( !mRenderer )
+    {
+      mRenderer = Text::Backend::Get().NewRenderer( mRenderingBackend );
+    }
+    RenderText();
+  }
+}
+
+void TextLabel::RequestTextRelayout()
+{
+  RelayoutRequest();
+}
 
 
-    // Update the visual
-    TextVisual::EnableRendererUpdate( mVisual );
+void TextLabel::RenderText()
+{
+  DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::RenderText IsAutoScrollEnabled[%s] [%p]\n", ( mController->IsAutoScrollEnabled())?"true":"false", this );
 
 
-    Padding padding;
-    Self().GetPadding( padding );
+  Actor self = Self();
+  Actor renderableActor;
 
 
-    Property::Map visualTransform;
-    visualTransform.Add( Toolkit::DevelVisual::Transform::Property::SIZE, contentSize )
-                   .Add( Toolkit::DevelVisual::Transform::Property::SIZE_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
-                   .Add( Toolkit::DevelVisual::Transform::Property::OFFSET, Vector2(padding.left, padding.top) )
-                   .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_POLICY, Vector2( Toolkit::DevelVisual::Transform::Policy::ABSOLUTE, Toolkit::DevelVisual::Transform::Policy::ABSOLUTE ) )
-                   .Add( Toolkit::DevelVisual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
-                   .Add( Toolkit::DevelVisual::Transform::Property::ANCHOR_POINT, Toolkit::Align::TOP_BEGIN );
-    mVisual.SetTransformAndSize( visualTransform, size );
+  float alignmentOffset = 0.f;
+  if( mRenderer )
+  {
+
+    Dali::Toolkit::TextLabel handle = Dali::Toolkit::TextLabel( GetOwner() );
+
+    renderableActor = mRenderer->Render( mController->GetView(),
+                                         handle,
+                                         Toolkit::DevelTextLabel::Property::TEXT_COLOR_ANIMATABLE,
+                                         alignmentOffset,
+                                         DepthIndex::CONTENT );
+  }
+
+  if( renderableActor != mRenderableActor )
+  {
+    UnparentAndReset( mRenderableActor );
+
+    if( renderableActor )
+    {
+      const Vector2& scrollOffset = mController->GetTextModel()->GetScrollPosition();
+      Padding padding;
+      self.GetPadding( padding );
+      renderableActor.SetPosition( scrollOffset.x + alignmentOffset + padding.left, scrollOffset.y + padding.top );
+
+      self.Add( renderableActor );
+    }
+    mRenderableActor = renderableActor;
 
     if ( mController->IsAutoScrollEnabled() )
     {
       SetUpAutoScrolling();
     }
 
     if ( mController->IsAutoScrollEnabled() )
     {
       SetUpAutoScrolling();
     }
-
-    mTextUpdateNeeded = false;
   }
 }
 
   }
 }
 
-void TextLabel::RequestTextRelayout()
-{
-  RelayoutRequest();
-}
-
 void TextLabel::SetUpAutoScrolling()
 {
   const Size& controlSize = mController->GetView().GetControlSize();
 void TextLabel::SetUpAutoScrolling()
 {
   const Size& controlSize = mController->GetView().GetControlSize();
-  const Size textNaturalSize = GetNaturalSize().GetVectorXY(); // As relayout of text may not be done at this point natural size is used to get size. Single line scrolling only.
+  const Size offScreenSize = GetNaturalSize().GetVectorXY(); // As relayout of text may not be done at this point natural size is used to get size. Single line scrolling only.
+  const float alignmentOffset = mController->GetAutoScrollLineAlignment();
   const Text::CharacterDirection direction = mController->GetAutoScrollDirection();
 
   const Text::CharacterDirection direction = mController->GetAutoScrollDirection();
 
-  DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::SetUpAutoScrolling textNaturalSize[%f,%f] controlSize[%f,%f]\n",
-                 textNaturalSize.x,textNaturalSize.y , controlSize.x,controlSize.y );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::SetUpAutoScrolling alignmentOffset[%f] offScreenSize[%f,%f] controlSize[%f,%f]\n",
+                 alignmentOffset, offScreenSize.x,offScreenSize.y , controlSize.x,controlSize.y );
 
   if ( !mTextScroller )
   {
 
   if ( !mTextScroller )
   {
@@ -945,27 +957,23 @@ void TextLabel::SetUpAutoScrolling()
     // If speed, loopCount or gap not set via property system then will need to create a TextScroller with defaults
     mTextScroller = Text::TextScroller::New( *this );
   }
     // If speed, loopCount or gap not set via property system then will need to create a TextScroller with defaults
     mTextScroller = Text::TextScroller::New( *this );
   }
+  mTextScroller->SetParameters( mRenderableActor, controlSize, offScreenSize, direction, alignmentOffset, mController->GetHorizontalAlignment() );
+
+  Actor self = Self();
+  self.Add( mTextScroller->GetScrollingText() );
+  self.Add( mTextScroller->GetSourceCamera() );
+}
 
 
-  // Create a texture of the text for scrolling
-  Text::TypesetterPtr typesetter = Text::Typesetter::New( mController->GetTextModel() );
-  PixelData data = typesetter->Render( textNaturalSize, Text::Typesetter::RENDER_TEXT_AND_STYLES, true, Pixel::RGBA8888 ); // ignore the horizontal alignment
-  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 );
-
-  // 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.SetSampler( 0u, sampler );
-
-  // Set parameters for scrolling
-  Renderer renderer = static_cast<Internal::Visual::Base&>( GetImplementation( mVisual ) ).GetRenderer();
-  mTextScroller->SetParameters( Self(), renderer, textureSet, controlSize, textNaturalSize, direction, mController->GetHorizontalAlignment(), mController->GetVerticalAlignment() );
+void TextLabel::OnStageConnect( Dali::Actor actor )
+{
+  if ( mHasBeenStaged )
+  {
+    RenderText();
+  }
+  else
+  {
+    mHasBeenStaged = true;
+  }
 }
 
 void TextLabel::ScrollingFinished()
 }
 
 void TextLabel::ScrollingFinished()
@@ -980,7 +988,7 @@ void TextLabel::ScrollingFinished()
 TextLabel::TextLabel()
 : Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
   mRenderingBackend( DEFAULT_RENDERING_BACKEND ),
 TextLabel::TextLabel()
 : Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
   mRenderingBackend( DEFAULT_RENDERING_BACKEND ),
-  mTextUpdateNeeded( false )
+  mHasBeenStaged( false )
 {
 }
 
 {
 }
 
index 85e94ab..f15acbf 100644 (file)
@@ -18,9 +18,6 @@
  *
  */
 
  *
  */
 
-// EXTERNAL INCLUDES
-#include <dali/public-api/object/property-map.h>
-
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/controls/control-impl.h>
 #include <dali-toolkit/public-api/controls/text-controls/text-label.h>
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/controls/control-impl.h>
 #include <dali-toolkit/public-api/controls/text-controls/text-label.h>
@@ -29,8 +26,6 @@
 #include <dali-toolkit/internal/text/text-scroller-interface.h>
 #include <dali-toolkit/internal/text/rendering/text-renderer.h>
 #include <dali-toolkit/internal/text/text-scroller.h>
 #include <dali-toolkit/internal/text/text-scroller-interface.h>
 #include <dali-toolkit/internal/text/rendering/text-renderer.h>
 #include <dali-toolkit/internal/text/text-scroller.h>
-#include <dali-toolkit/internal/visuals/text/text-visual.h>
-
 
 namespace Dali
 {
 
 namespace Dali
 {
@@ -137,6 +132,14 @@ private:
   TextLabel(const TextLabel&);
   TextLabel& operator=(const TextLabel& rhs);
 
   TextLabel(const TextLabel&);
   TextLabel& operator=(const TextLabel& rhs);
 
+  // Connection needed to re-render text, when a Text Label returns to the stage
+  void OnStageConnect( Dali::Actor actor );
+
+  /**
+   * @brief Render view, create and attach actor(s) to this Text Label
+   */
+  void RenderText();
+
   /**
    * @brief Set up Autoscrolling
    */
   /**
    * @brief Set up Autoscrolling
    */
@@ -145,12 +148,11 @@ private:
 private: // Data
 
   Text::ControllerPtr mController;
 private: // Data
 
   Text::ControllerPtr mController;
+  Text::RendererPtr mRenderer;
   Text::TextScrollerPtr mTextScroller;
   Text::TextScrollerPtr mTextScroller;
-
-  Toolkit::Visual::Base mVisual;
-
+  Actor mRenderableActor;
   int mRenderingBackend;
   int mRenderingBackend;
-  bool mTextUpdateNeeded:1;
+  bool mHasBeenStaged:1;
 };
 
 } // namespace Internal
 };
 
 } // namespace Internal
index 66bb797..78aba49 100644 (file)
@@ -21,7 +21,6 @@
 // EXTERNAL INCLUDES
 #include <dali/devel-api/text-abstraction/font-client.h>
 #include <memory.h>
 // EXTERNAL INCLUDES
 #include <dali/devel-api/text-abstraction/font-client.h>
 #include <memory.h>
-#include <dali/public-api/common/constants.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/rendering/view-model.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/rendering/view-model.h>
@@ -43,7 +42,7 @@ namespace
  */
 struct GlyphData
 {
  */
 struct GlyphData
 {
-  Devel::PixelBuffer                           bitmapBuffer;     ///< The buffer of the whole bitmap. The format is RGBA8888.
+  uint32_t*                                    bitmapBuffer;     ///< The buffer of the whole bitmap. The format is RGBA8888.
   Vector2*                                     position;         ///< The position of the glyph.
   TextAbstraction::FontClient::GlyphBufferData glyphBitmap;      ///< The glyph's bitmap.
   unsigned int                                 width;            ///< The bitmap's width.
   Vector2*                                     position;         ///< The position of the glyph.
   TextAbstraction::FontClient::GlyphBufferData glyphBitmap;      ///< The glyph's bitmap.
   unsigned int                                 width;            ///< The bitmap's width.
@@ -58,14 +57,10 @@ struct GlyphData
  * @param[in] data Struct which contains the glyph's data and the bitmap's data.
  * @param[in] position The position of the glyph.
  * @param[in] color The color of the glyph.
  * @param[in] data Struct which contains the glyph's data and the bitmap's data.
  * @param[in] position The position of the glyph.
  * @param[in] color The color of the glyph.
- * @param[in] style The style of the text.
- * @param[in] pixelFormat The format of the pixel in the image that the text is rendered as (i.e. either Pixel::BGRA8888 or Pixel::L8).
  */
  */
-void TypesetGlyph( GlyphData& data,
+void TypesetGlyph( const GlyphData& data,
                    const Vector2* const position,
                    const Vector2* const position,
-                   const Vector4* const color,
-                   Typesetter::Style style,
-                   Pixel::Format pixelFormat )
+                   const Vector4* const color )
 {
   if( ( 0u == data.glyphBitmap.width ) || ( 0u == data.glyphBitmap.height ) )
   {
 {
   if( ( 0u == data.glyphBitmap.width ) || ( 0u == data.glyphBitmap.height ) )
   {
@@ -76,179 +71,71 @@ void TypesetGlyph( GlyphData& data,
   const int widthMinusOne = static_cast<int>( data.width - 1u );
   const int heightMinusOne = static_cast<int>( data.height - 1u );
 
   const int widthMinusOne = static_cast<int>( data.width - 1u );
   const int heightMinusOne = static_cast<int>( data.height - 1u );
 
-  if ( Pixel::RGBA8888 == pixelFormat )
-  {
-    // Whether the given glyph is a color one.
-    const bool isColorGlyph = Pixel::BGRA8888 == data.glyphBitmap.format;
+  // Whether the given glyph is a color one.
+  const bool isColorGlyph = Pixel::BGRA8888 == data.glyphBitmap.format;
 
 
-    // Pointer to the color glyph if there is one.
-    const uint32_t* const colorGlyphBuffer = isColorGlyph ? reinterpret_cast<uint32_t*>( data.glyphBitmap.buffer ) : NULL;
+  // Pointer to the color glyph if there is one.
+  const uint32_t* const colorGlyphBuffer = isColorGlyph ? reinterpret_cast<uint32_t*>( data.glyphBitmap.buffer ) : NULL;
 
 
-    // Pack the given color into a 32bit buffer. The alpha channel will be updated later for each pixel.
-    // The format is RGBA8888.
-    uint32_t packedColor = 0u;
-    uint8_t* packedColorBuffer = reinterpret_cast<uint8_t*>( &packedColor );
-    *( packedColorBuffer + 2 ) = static_cast<uint8_t>( color->b * 255.f );
-    *( packedColorBuffer + 1 ) = static_cast<uint8_t>( color->g * 255.f );
-      *packedColorBuffer       = static_cast<uint8_t>( color->r * 255.f );
+  // Pack the given color into a 32bit buffer. The alpha channel will be updated later for each pixel.
+  // The format is RGBA8888.
+  uint32_t packedColor = 0u;
+  uint8_t* packedColorBuffer = reinterpret_cast<uint8_t*>( &packedColor );
+  *( packedColorBuffer + 2 ) = static_cast<uint8_t>( color->b * 255.f );
+  *( packedColorBuffer + 1 ) = static_cast<uint8_t>( color->g * 255.f );
+    *packedColorBuffer       = static_cast<uint8_t>( color->r * 255.f );
 
 
-    // Initial vertical offset.
-    const int yOffset = data.verticalOffset + position->y;
+  // Initial vertical offset.
+  const int yOffset = data.verticalOffset + position->y;
 
 
-    // Traverse the pixels of the glyph line per line.
-    for( int lineIndex = 0, glyphHeight = static_cast<int>( data.glyphBitmap.height ); lineIndex < glyphHeight; ++lineIndex )
+  // Traverse the pixels of the glyph line per line.
+  for( int lineIndex = 0, glyphHeight = static_cast<int>( data.glyphBitmap.height ); lineIndex < glyphHeight; ++lineIndex )
+  {
+    const int yOffsetIndex = yOffset + lineIndex;
+    if( ( 0 > yOffsetIndex ) || ( yOffsetIndex > heightMinusOne ) )
     {
     {
-      const int yOffsetIndex = yOffset + lineIndex;
-      if( ( 0 > yOffsetIndex ) || ( yOffsetIndex > heightMinusOne ) )
-      {
-        // Do not write out of bounds.
-        break;
-      }
-
-      const int verticalOffset = yOffsetIndex * data.width;
-      const int xOffset = data.horizontalOffset + position->x;
-      const int glyphBufferOffset = lineIndex * static_cast<int>( data.glyphBitmap.width );
-      for( int index = 0, glyphWidth = static_cast<int>( data.glyphBitmap.width ); index < glyphWidth; ++index )
-      {
-        const int xOffsetIndex = xOffset + index;
-        if( ( 0 > xOffsetIndex ) || ( xOffsetIndex > widthMinusOne ) )
-        {
-          // Don't write out of bounds.
-          break;
-        }
-
-        uint32_t* bitmapBuffer = reinterpret_cast< uint32_t* >( data.bitmapBuffer.GetBuffer() );
-
-        if( isColorGlyph )
-        {
-          // Retrieves the color from the color glyph. The format is BGRA8888.
-          uint32_t packedColorGlyph = *( colorGlyphBuffer + glyphBufferOffset + index );
-          uint8_t* packedColorGlyphBuffer = reinterpret_cast<uint8_t*>( &packedColorGlyph );
-
-          if( Typesetter::STYLE_SHADOW == style )
-          {
-            // The shadow of color glyph needs to have the shadow color.
-            *( packedColorGlyphBuffer + 2 ) = static_cast<uint8_t>( color->b * 255.f );
-            *( packedColorGlyphBuffer + 1 ) = static_cast<uint8_t>( color->g * 255.f );
-              *packedColorGlyphBuffer       = static_cast<uint8_t>( color->r * 255.f );
-          }
-          else
-          {
-            std::swap( *packedColorGlyphBuffer, *( packedColorGlyphBuffer + 2u ) ); // Swap B and R.
-          }
-
-          // Update the alpha channel.
-          if( Typesetter::STYLE_MASK == style )
-          {
-            // Create an alpha mask for color glyph.
-            *( packedColorGlyphBuffer + 3u ) = 0u;
-          }
-          else
-          {
-            *( packedColorGlyphBuffer + 3u ) = static_cast<uint8_t>( color->a * static_cast<float>( *( packedColorGlyphBuffer + 3u ) ) );
-          }
-
-          // Set the color into the final pixel buffer.
-          *( bitmapBuffer + verticalOffset + xOffsetIndex ) = packedColorGlyph;
-        }
-        else
-        {
-          // 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
-            uint32_t& currentColor = *( bitmapBuffer + verticalOffset + xOffsetIndex );
-            uint8_t* packedCurrentColorBuffer = reinterpret_cast<uint8_t*>( &currentColor );
-
-            uint8_t currentAlpha = *( packedCurrentColorBuffer + 3u );
-            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).
-            *( packedColorBuffer + 3u ) = std::max( currentAlpha, newAlpha );
-
-            // Set the color into the final pixel buffer.
-            currentColor = packedColor;
-          }
-        }
-      }
+      // Do not write out of bounds.
+      break;
     }
     }
-  }
-  else
-  {
-    // Initial vertical offset.
-    const int yOffset = data.verticalOffset + position->y;
 
 
-    // Traverse the pixels of the glyph line per line.
-    for( int lineIndex = 0, glyphHeight = static_cast<int>( data.glyphBitmap.height ); lineIndex < glyphHeight; ++lineIndex )
+    const int verticalOffset = yOffsetIndex * data.width;
+    const int xOffset = data.horizontalOffset + position->x;
+    const int glyphBufferOffset = lineIndex * static_cast<int>( data.glyphBitmap.width );
+    for( int index = 0, glyphWidth = static_cast<int>( data.glyphBitmap.width ); index < glyphWidth; ++index )
     {
     {
-      const int yOffsetIndex = yOffset + lineIndex;
-      if( ( 0 > yOffsetIndex ) || ( yOffsetIndex > heightMinusOne ) )
+      const int xOffsetIndex = xOffset + index;
+      if( ( 0 > xOffsetIndex ) || ( xOffsetIndex > widthMinusOne ) )
       {
       {
-        // Do not write out of bounds.
+        // Don't write out of bounds.
         break;
       }
 
         break;
       }
 
-      const int verticalOffset = yOffsetIndex * data.width;
-      const int xOffset = data.horizontalOffset + position->x;
-      const int glyphBufferOffset = lineIndex * static_cast<int>( data.glyphBitmap.width );
-      for( int index = 0, glyphWidth = static_cast<int>( data.glyphBitmap.width ); index < glyphWidth; ++index )
+      if( isColorGlyph )
       {
       {
-        const int xOffsetIndex = xOffset + index;
-        if( ( 0 > xOffsetIndex ) || ( xOffsetIndex > widthMinusOne ) )
-        {
-          // Don't write out of bounds.
-          break;
-        }
+        // Retrieves the color from the glyph. The format is BGRA8888.
+        uint32_t packedColorGlyph = *( colorGlyphBuffer + glyphBufferOffset + index );
 
 
-        uint8_t* bitmapBuffer = reinterpret_cast< uint8_t* >( data.bitmapBuffer.GetBuffer() );
+        // Update the alpha channel.
+        uint8_t* packedColorGlyphBuffer = reinterpret_cast<uint8_t*>( &packedColorGlyph );
+        std::swap( *packedColorGlyphBuffer, *( packedColorGlyphBuffer + 2u ) ); // Swap B and R.
+        *( packedColorGlyphBuffer + 3u ) = static_cast<uint8_t>( color->a * static_cast<float>( *( packedColorGlyphBuffer + 3u ) ) );
 
 
+        // Set the color into the final pixel buffer.
+        *( data.bitmapBuffer + verticalOffset + xOffsetIndex ) = packedColorGlyph;
+      }
+      else
+      {
         // Update the alpha channel.
         const uint8_t alpha = *( data.glyphBitmap.buffer + glyphBufferOffset + index );
         // Update the alpha channel.
         const uint8_t alpha = *( data.glyphBitmap.buffer + glyphBufferOffset + index );
+        *( packedColorBuffer + 3u ) = static_cast<uint8_t>( color->a * static_cast<float>( alpha ) );
 
 
-        // 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 ) );
-//          printf("y: %d, x: %d: alpha: %u, currentAlpha: %u, newAlpha: %u, a: %u\n", yOffsetIndex, xOffsetIndex, alpha, currentAlpha, newAlpha, std::max( currentAlpha, newAlpha ) );
-
-          // 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 );
-        }
+        // Set the color into the final pixel buffer.
+        *( data.bitmapBuffer + verticalOffset + xOffsetIndex ) = packedColor;
       }
     }
   }
 }
 
       }
     }
   }
 }
 
-bool IsGlyphUnderlined( GlyphIndex index,
-                         const Vector<GlyphRun>& underlineRuns )
-{
-  for( Vector<GlyphRun>::ConstIterator it = underlineRuns.Begin(),
-         endIt = underlineRuns.End();
-         it != endIt;
-       ++it )
-  {
-    const GlyphRun& run = *it;
-
-    if( ( run.glyphIndex <= index ) && ( index < run.glyphIndex + run.numberOfGlyphs ) )
-    {
-      return true;
-    }
-  }
-
-  return false;
-}
-
 } // namespace
 
 TypesetterPtr Typesetter::New( const ModelInterface* const model )
 } // namespace
 
 TypesetterPtr Typesetter::New( const ModelInterface* const model )
@@ -261,7 +148,7 @@ ViewModel* Typesetter::GetViewModel()
   return mModel;
 }
 
   return mModel;
 }
 
-PixelData Typesetter::Render( const Vector2& size, RenderBehaviour behaviour, bool ignoreHorizontalAlignment, Pixel::Format pixelFormat )
+PixelData Typesetter::Render( const Vector2& size )
 {
   // @todo. This initial implementation for a TextLabel has only one visible page.
 
 {
   // @todo. This initial implementation for a TextLabel has only one visible page.
 
@@ -293,73 +180,6 @@ PixelData Typesetter::Render( const Vector2& size, RenderBehaviour behaviour, bo
     }
   }
 
     }
   }
 
-  // Generate the image buffers of the text for each different style first,
-  // then combine all of them together as one final image buffer. We try to
-  // do all of these in CPU only, so that once the final texture is generated,
-  // no calculation is needed in GPU during each frame.
-
-  const unsigned int bufferWidth = static_cast<unsigned int>( size.width );
-  const unsigned int bufferHeight = static_cast<unsigned int>( size.height );
-
-  const unsigned int bufferSizeInt = bufferWidth * bufferHeight;
-  const unsigned int bufferSizeChar = 4u * bufferSizeInt;
-
-  Length numberOfGlyphs = mModel->GetNumberOfGlyphs();
-
-  Devel::PixelBuffer imageBuffer;
-
-  if( RENDER_MASK == behaviour )
-  {
-    // Generate the image buffer as an alpha mask for color glyphs.
-    imageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_MASK, ignoreHorizontalAlignment, pixelFormat, penY, 0u, numberOfGlyphs - 1 );
-  }
-  else if( RENDER_NO_TEXT == behaviour )
-  {
-    // Generate an empty image buffer so that it can been combined with the image buffers for styles
-    imageBuffer = Devel::PixelBuffer::New( bufferWidth, bufferHeight, Pixel::RGBA8888 );
-    memset( imageBuffer.GetBuffer(), 0u, bufferSizeChar );
-  }
-  else
-  {
-    // Generate the image buffer for the text with no style.
-    imageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_NONE, ignoreHorizontalAlignment, pixelFormat, penY, 0u, numberOfGlyphs -1 );
-  }
-
-  if ( ( RENDER_NO_STYLES != behaviour ) && ( RENDER_MASK != behaviour ) )
-  {
-    // @todo. Support shadow and underline for partial text later on.
-
-    // Generate the shadow if enabled
-    const Vector2& shadowOffset = mModel->GetShadowOffset();
-    if ( fabsf( shadowOffset.x ) > Math::MACHINE_EPSILON_1 || fabsf( shadowOffset.y ) > Math::MACHINE_EPSILON_1 )
-    {
-      // Create the image buffer for shadow
-      Devel::PixelBuffer shadowImageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_SHADOW, ignoreHorizontalAlignment, pixelFormat, penY, 0u, numberOfGlyphs - 1 );
-
-      // Combine the two buffers
-      imageBuffer = CombineImageBuffer( imageBuffer, shadowImageBuffer, bufferWidth, bufferHeight );
-    }
-
-    // Generate the underline if enabled
-    const bool underlineEnabled = mModel->IsUnderlineEnabled();
-    if ( underlineEnabled )
-    {
-      // Create the image buffer for underline
-      Devel::PixelBuffer underlineImageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_UNDERLINE, ignoreHorizontalAlignment, pixelFormat, penY, 0u, numberOfGlyphs - 1 );
-
-      // Combine the two buffers
-      imageBuffer = CombineImageBuffer( imageBuffer, underlineImageBuffer, bufferWidth, bufferHeight );
-    }
-  }
-
-  // Create the final PixelData for the combined image buffer
-  PixelData pixelData = Devel::PixelBuffer::Convert( imageBuffer );
-
-  return pixelData;
-}
-
-Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth, const unsigned int bufferHeight, Typesetter::Style style, bool ignoreHorizontalAlignment, Pixel::Format pixelFormat, int verticalOffset, GlyphIndex fromGlyphIndex, GlyphIndex toGlyphIndex )
-{
   // Retrieve lines, glyphs, positions and colors from the view model.
   const Length modelNumberOfLines = mModel->GetNumberOfLines();
   const LineRun* const modelLinesBuffer = mModel->GetLines();
   // Retrieve lines, glyphs, positions and colors from the view model.
   const Length modelNumberOfLines = mModel->GetNumberOfLines();
   const LineRun* const modelLinesBuffer = mModel->GetLines();
@@ -370,26 +190,26 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth
   const ColorIndex* const colorIndexBuffer = mModel->GetColorIndices();
 
   // Whether to use the default color.
   const ColorIndex* const colorIndexBuffer = mModel->GetColorIndices();
 
   // Whether to use the default color.
-  const bool useDefaultColor = ( NULL == colorsBuffer );
+  const bool useDefaultColor = NULL == colorsBuffer;
   const Vector4& defaultColor = mModel->GetDefaultColor();
 
   // Create and initialize the pixel buffer.
   GlyphData glyphData;
   const Vector4& defaultColor = mModel->GetDefaultColor();
 
   // Create and initialize the pixel buffer.
   GlyphData glyphData;
-  glyphData.verticalOffset = verticalOffset;
-  glyphData.width = bufferWidth;
-  glyphData.height = bufferHeight;
-  glyphData.bitmapBuffer = Devel::PixelBuffer::New( bufferWidth, bufferHeight, pixelFormat );
+  glyphData.verticalOffset = penY;
 
 
-  if ( Pixel::RGBA8888 == pixelFormat )
-  {
-    const unsigned int bufferSizeInt = bufferWidth * bufferHeight;
-    const unsigned int bufferSizeChar = 4u * bufferSizeInt;
-    memset( glyphData.bitmapBuffer.GetBuffer(), 0u, bufferSizeChar );
-  }
-  else
-  {
-    memset( glyphData.bitmapBuffer.GetBuffer(), 0, bufferWidth * bufferHeight );
-  }
+  glyphData.width = static_cast<unsigned int>( size.width );
+  glyphData.height = static_cast<unsigned int>( size.height );
+  const unsigned int bufferSizeInt = glyphData.width * glyphData.height;
+  const unsigned int bufferSizeChar = 4u * bufferSizeInt;
+  glyphData.bitmapBuffer = new uint32_t[ bufferSizeInt ]; // This array will get deleted by PixelData because of the DELETE_ARRAY parameter.
+  memset( glyphData.bitmapBuffer, 0u, bufferSizeChar );
+
+  PixelData pixelData = PixelData::New( reinterpret_cast<uint8_t*>( glyphData.bitmapBuffer ),
+                                        bufferSizeChar,
+                                        glyphData.width,
+                                        glyphData.height,
+                                        Pixel::RGBA8888, // The format is RGBA8888 because is the format accepted by the image atlas manager.
+                                        PixelData::DELETE_ARRAY );
 
   // Get a handle of the font client. Used to retrieve the bitmaps of the glyphs.
   TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
 
   // Get a handle of the font client. Used to retrieve the bitmaps of the glyphs.
   TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
@@ -400,54 +220,15 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth
     const LineRun& line = *( modelLinesBuffer + lineIndex );
 
     // Sets the horizontal offset of the line.
     const LineRun& line = *( modelLinesBuffer + lineIndex );
 
     // Sets the horizontal offset of the line.
-    glyphData.horizontalOffset = ignoreHorizontalAlignment ? 0 : static_cast<int>( line.alignmentOffset );
+    glyphData.horizontalOffset = static_cast<int>( line.alignmentOffset );
 
     // Increases the vertical offset with the line's ascender.
     glyphData.verticalOffset += static_cast<int>( line.ascender );
 
 
     // Increases the vertical offset with the line's ascender.
     glyphData.verticalOffset += static_cast<int>( line.ascender );
 
-    if ( style == Typesetter::STYLE_SHADOW )
-    {
-      const Vector2& shadowOffset = mModel->GetShadowOffset();
-      glyphData.horizontalOffset += shadowOffset.x;
-      if ( lineIndex == 0u )
-      {
-        // Only need to add the vertical shadow offset for once
-        glyphData.verticalOffset += shadowOffset.y;
-      }
-    }
-
-    const bool underlineEnabled = mModel->IsUnderlineEnabled();
-    const Vector4& underlineColor = mModel->GetUnderlineColor();
-    const float underlineHeight = mModel->GetUnderlineHeight();
-
-    // Get the underline runs.
-    const Length numberOfUnderlineRuns = mModel->GetNumberOfUnderlineRuns();
-    Vector<GlyphRun> underlineRuns;
-    underlineRuns.Resize( numberOfUnderlineRuns );
-    mModel->GetUnderlineRuns( underlineRuns.Begin(), 0u, numberOfUnderlineRuns );
-
-    bool thereAreUnderlinedGlyphs = false;
-
-    float currentUnderlinePosition = 0.0f;
-    float currentUnderlineThickness = underlineHeight;
-    float maxUnderlineThickness = currentUnderlineThickness;
-
-    FontId lastUnderlinedFontId = 0;
-
-    float lineExtentLeft = bufferWidth;
-    float lineExtentRight = 0.0f;
-    float baseline = 0.0f;
-
     // Traverses the glyphs of the line.
     const GlyphIndex endGlyphIndex = std::min( numberOfGlyphs, line.glyphRun.glyphIndex + line.glyphRun.numberOfGlyphs );
     for( GlyphIndex glyphIndex = line.glyphRun.glyphIndex; glyphIndex < endGlyphIndex; ++glyphIndex )
     {
     // Traverses the glyphs of the line.
     const GlyphIndex endGlyphIndex = std::min( numberOfGlyphs, line.glyphRun.glyphIndex + line.glyphRun.numberOfGlyphs );
     for( GlyphIndex glyphIndex = line.glyphRun.glyphIndex; glyphIndex < endGlyphIndex; ++glyphIndex )
     {
-      if ( glyphIndex < fromGlyphIndex || glyphIndex > toGlyphIndex )
-      {
-        // Ignore any glyph that out of the specified range
-        continue;
-      }
-
       // Retrieve the glyph's info.
       const GlyphInfo* const glyphInfo = glyphsBuffer + glyphIndex;
 
       // Retrieve the glyph's info.
       const GlyphInfo* const glyphInfo = glyphsBuffer + glyphIndex;
 
@@ -458,84 +239,12 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth
         continue;
       }
 
         continue;
       }
 
-      const bool underlineGlyph = underlineEnabled || IsGlyphUnderlined( glyphIndex, underlineRuns );
-      thereAreUnderlinedGlyphs = thereAreUnderlinedGlyphs || underlineGlyph;
-
-      // Are we still using the same fontId as previous
-      if( underlineGlyph && ( glyphInfo->fontId != lastUnderlinedFontId ) )
-      {
-        // We need to fetch fresh font underline metrics
-        FontMetrics fontMetrics;
-        fontClient.GetFontMetrics( glyphInfo->fontId, fontMetrics );
-        currentUnderlinePosition = ceil( fabsf( fontMetrics.underlinePosition ) );
-        const float descender = ceil( fabsf( fontMetrics.descender ) );
-
-        if( fabsf( underlineHeight ) < Math::MACHINE_EPSILON_1000 )
-        {
-          currentUnderlineThickness = fontMetrics.underlineThickness;
-
-          // Ensure underline will be at least a pixel high
-          if ( currentUnderlineThickness < 1.0f )
-          {
-            currentUnderlineThickness = 1.0f;
-          }
-          else
-          {
-            currentUnderlineThickness = ceil( currentUnderlineThickness );
-          }
-        }
-
-        // The underline thickness should be the max underline thickness of all glyphs of the line.
-        if ( currentUnderlineThickness > maxUnderlineThickness )
-        {
-          maxUnderlineThickness = currentUnderlineThickness;
-        }
-
-        // Clamp the underline position at the font descender and check for ( as EFL describes it ) a broken font
-        if( currentUnderlinePosition > descender )
-        {
-          currentUnderlinePosition = descender;
-        }
-
-        if( fabsf( currentUnderlinePosition ) < Math::MACHINE_EPSILON_1000 )
-        {
-          // Move offset down by one ( EFL behavior )
-          currentUnderlinePosition = 1.0f;
-        }
-
-        lastUnderlinedFontId = glyphInfo->fontId;
-      } // underline
-
       // Retrieves the glyph's position.
       const Vector2* const position = positionBuffer + glyphIndex;
       // Retrieves the glyph's position.
       const Vector2* const position = positionBuffer + glyphIndex;
-      if ( baseline < position->y + glyphInfo->yBearing )
-      {
-        baseline = position->y + glyphInfo->yBearing;
-      }
-
-      // Calculate the positions of leftmost and rightmost glyphs in the current line
-      if ( position->x < lineExtentLeft)
-      {
-        lineExtentLeft = position->x;
-      }
-
-      if ( position->x + glyphInfo->width > lineExtentRight)
-      {
-        lineExtentRight = position->x + glyphInfo->width;
-      }
 
       // Retrieves the glyph's color.
       const ColorIndex colorIndex = *( colorIndexBuffer + glyphIndex );
 
       // Retrieves the glyph's color.
       const ColorIndex colorIndex = *( colorIndexBuffer + glyphIndex );
-
-      const Vector4* color;
-      if ( style == Typesetter::STYLE_SHADOW )
-      {
-        color = &( mModel->GetShadowColor() );
-      }
-      else
-      {
-        color = ( useDefaultColor || ( 0u == colorIndex ) ) ? &defaultColor : colorsBuffer + ( colorIndex - 1u );
-      }
+      const Vector4* const color = ( useDefaultColor || ( 0u == colorIndex ) ) ? &defaultColor : colorsBuffer + ( colorIndex - 1u );
 
       // Retrieves the glyph's bitmap.
       glyphData.glyphBitmap.buffer = NULL;
 
       // Retrieves the glyph's bitmap.
       glyphData.glyphBitmap.buffer = NULL;
@@ -550,49 +259,11 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth
       {
         TypesetGlyph( glyphData,
                       position,
       {
         TypesetGlyph( glyphData,
                       position,
-                      color,
-                      style,
-                      pixelFormat);
+                      color );
         // delete the glyphBitmap.buffer as it is now copied into glyphData.bitmapBuffer
         delete []glyphData.glyphBitmap.buffer;
         glyphData.glyphBitmap.buffer = NULL;
         // delete the glyphBitmap.buffer as it is now copied into glyphData.bitmapBuffer
         delete []glyphData.glyphBitmap.buffer;
         glyphData.glyphBitmap.buffer = NULL;
-      }
-    }
 
 
-    // Draw the underline from the leftmost glyph to the rightmost glyph
-    if ( thereAreUnderlinedGlyphs && style == Typesetter::STYLE_UNDERLINE )
-    {
-      int underlineYOffset = glyphData.verticalOffset + baseline + currentUnderlinePosition;
-
-      for( unsigned int y = underlineYOffset; y < underlineYOffset + maxUnderlineThickness; y++ )
-      {
-        if( ( y < 0 ) || ( y > bufferHeight - 1 ) )
-        {
-          // Do not write out of bounds.
-          break;
-        }
-
-        for( unsigned int x = glyphData.horizontalOffset + lineExtentLeft; x <= glyphData.horizontalOffset + lineExtentRight; x++ )
-        {
-          if( ( x < 0 ) || ( x > bufferWidth - 1 ) )
-          {
-            // Do not write out of bounds.
-            break;
-          }
-
-          // Always RGBA image for text with styles
-          uint32_t* bitmapBuffer = reinterpret_cast< uint32_t* >( glyphData.bitmapBuffer.GetBuffer() );
-          uint32_t underlinePixel = *( bitmapBuffer + y * glyphData.width + x );
-          uint8_t* underlinePixelBuffer = reinterpret_cast<uint8_t*>( &underlinePixel );
-
-          // Write the underline color to the pixel buffer
-          *( underlinePixelBuffer ) = static_cast<uint8_t>( underlineColor.r * 255.f );
-          *( underlinePixelBuffer + 1u ) = static_cast<uint8_t>( underlineColor.g * 255.f );
-          *( underlinePixelBuffer + 2u ) = static_cast<uint8_t>( underlineColor.b * 255.f );
-          *( underlinePixelBuffer + 3u ) = static_cast<uint8_t>( underlineColor.a * 255.f );
-
-          *( bitmapBuffer + y * glyphData.width + x ) = underlinePixel;
-        }
       }
     }
 
       }
     }
 
@@ -600,70 +271,7 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth
     glyphData.verticalOffset += static_cast<int>( -line.descender );
   }
 
     glyphData.verticalOffset += static_cast<int>( -line.descender );
   }
 
-  return glyphData.bitmapBuffer;
-}
-
-Devel::PixelBuffer Typesetter::CombineImageBuffer( Devel::PixelBuffer topPixelBuffer, Devel::PixelBuffer bottomPixelBuffer, const unsigned int bufferWidth, const unsigned int bufferHeight )
-{
-  unsigned char* topBuffer = topPixelBuffer.GetBuffer();
-  unsigned char* bottomBuffer = bottomPixelBuffer.GetBuffer();
-
-  Devel::PixelBuffer combinedPixelBuffer;
-
-  if ( topBuffer == NULL && bottomBuffer == NULL )
-  {
-    // Nothing to do if both buffers are empty.
-    return combinedPixelBuffer;
-  }
-
-  if ( topBuffer == NULL )
-  {
-    // Nothing to do if topBuffer is empty.
-    return bottomPixelBuffer;
-  }
-
-  if ( bottomBuffer == NULL )
-  {
-    // Nothing to do if bottomBuffer is empty.
-    return topPixelBuffer;
-  }
-
-  // Always combine two RGBA images
-  const unsigned int bufferSizeInt = bufferWidth * bufferHeight;
-  const unsigned int bufferSizeChar = 4u * bufferSizeInt;
-
-  combinedPixelBuffer = Devel::PixelBuffer::New( bufferWidth, bufferHeight, Pixel::RGBA8888 );
-  uint8_t* combinedBuffer = reinterpret_cast< uint8_t* >( combinedPixelBuffer.GetBuffer() );
-  memset( combinedBuffer, 0u, bufferSizeChar );
-
-  for (unsigned int pixelIndex = 0; pixelIndex < bufferSizeInt; pixelIndex++)
-  {
-    // If the alpha of the pixel in either buffer is not fully opaque, blend the two pixels.
-    // Otherwise, copy pixel from topBuffer to combinedBuffer.
-
-    unsigned int alphaBuffer1 = topBuffer[pixelIndex*4+3];
-    unsigned int alphaBuffer2 = bottomBuffer[pixelIndex*4+3];
-
-    if ( alphaBuffer1 != 255 || alphaBuffer2 != 255 )
-    {
-      // At least one pixel is not fully opaque
-      // "Over" blend the the pixel from topBuffer with the pixel in bottomBuffer
-      combinedBuffer[pixelIndex*4] = ( topBuffer[pixelIndex*4] * topBuffer[pixelIndex*4+3] / 255 ) + ( bottomBuffer[pixelIndex*4] * bottomBuffer[pixelIndex*4+3] * ( 255 - topBuffer[pixelIndex*4+3] ) / ( 255*255 ) );
-      combinedBuffer[pixelIndex*4+1] = ( topBuffer[pixelIndex*4+1] * topBuffer[pixelIndex*4+3] / 255 ) + ( bottomBuffer[pixelIndex*4+1] * bottomBuffer[pixelIndex*4+3] * ( 255 - topBuffer[pixelIndex*4+3] ) / ( 255*255 ) );
-      combinedBuffer[pixelIndex*4+2] = ( topBuffer[pixelIndex*4+2] * topBuffer[pixelIndex*4+3] / 255 ) + ( bottomBuffer[pixelIndex*4+2] * bottomBuffer[pixelIndex*4+3] * ( 255 - topBuffer[pixelIndex*4+3] ) / ( 255*255 ) );
-      combinedBuffer[pixelIndex*4+3] = topBuffer[pixelIndex*4+3] + ( bottomBuffer[pixelIndex*4+3] * ( 255 - topBuffer[pixelIndex*4+3] ) / 255 );
-    }
-    else
-    {
-      // Copy the pixel from topBuffer to combinedBuffer
-      combinedBuffer[pixelIndex*4] = topBuffer[pixelIndex*4];
-      combinedBuffer[pixelIndex*4+1] = topBuffer[pixelIndex*4+1];
-      combinedBuffer[pixelIndex*4+2] = topBuffer[pixelIndex*4+2];
-      combinedBuffer[pixelIndex*4+3] = topBuffer[pixelIndex*4+3];
-    }
-  }
-
-  return combinedPixelBuffer;
+  return pixelData;
 }
 
 Typesetter::Typesetter( const ModelInterface* const model )
 }
 
 Typesetter::Typesetter( const ModelInterface* const model )
index 285348e..a5aab65 100644 (file)
 // EXTERNAL INCLUDES
 #include <dali/public-api/common/intrusive-ptr.h>
 #include <dali/public-api/object/ref-object.h>
 // EXTERNAL INCLUDES
 #include <dali/public-api/common/intrusive-ptr.h>
 #include <dali/public-api/object/ref-object.h>
-#include <dali/public-api/images/pixel.h>
 #include <dali/public-api/images/pixel-data.h>
 #include <dali/public-api/images/pixel-data.h>
-#include <dali/devel-api/text-abstraction/text-abstraction-definitions.h>
-#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
 
 namespace Dali
 {
 
 namespace Dali
 {
@@ -46,33 +43,6 @@ typedef IntrusivePtr<Typesetter> TypesetterPtr;
  */
 class Typesetter : public RefObject
 {
  */
 class Typesetter : public RefObject
 {
-public:
-
-  /**
-   * @brief Behaviours of how to render the text.
-   */
-  enum RenderBehaviour
-  {
-    RENDER_TEXT_AND_STYLES,  ///< Render both the text and its styles
-    RENDER_NO_TEXT,          ///< Do not render the text itself
-    RENDER_NO_STYLES,        ///< Do not render any styles
-    RENDER_MASK              ///< Render an alpha mask (for color glyphs with no color animation, e.g. emoji)
-  };
-
-  /**
-   * @brief Styles of the text.
-   */
-  enum Style
-  {
-    STYLE_NONE,              ///< No style
-    STYLE_MASK,              ///< Alpha mask
-    STYLE_SHADOW,            ///< Hard shadow
-    STYLE_SOFT_SHADOW,       ///< Soft shadow
-    STYLE_UNDERLINE,         ///< Underline
-    STYLE_OUTLINE,           ///< Outline
-    STYLE_BACKGROUND         ///< Text background
-  };
-
 public: // Constructor.
   /**
    * @brief Creates a Typesetter instance.
 public: // Constructor.
   /**
    * @brief Creates a Typesetter instance.
@@ -98,17 +68,15 @@ public:
    * Does the following operations:
    * - Finds the visible pages needed to be rendered.
    * - Elide glyphs if needed.
    * Does the following operations:
    * - Finds the visible pages needed to be rendered.
    * - Elide glyphs if needed.
-   * - Creates image buffers for diffrent text styles with the given size.
-   * - Combines different image buffers to create the pixel data used to generate the final image
+   * - Retrieves the data buffers from the text model.
+   * - Creates the pixel data used to generate the final image with the given size.
+   * - Traverse the visible glyphs, retrieve their bitmaps and compose the final pixel data.
    *
    * @param[in] size The renderer size.
    *
    * @param[in] size The renderer size.
-   * @param[in] behaviour The behaviour of how to render the text (i.e. whether to render the text only or the styles only or both).
-   * @param[in] ignoreHorizontalAlignment Whether to ignore the horizontal alignment (i.e. always render as if HORIZONTAL_ALIGN_BEGIN).
-   * @param[in] pixelFormat The format of the pixel in the image that the text is rendered as (i.e. either Pixel::BGRA8888 or Pixel::L8).
    *
    * @return A pixel data with the text rendered.
    */
    *
    * @return A pixel data with the text rendered.
    */
-  PixelData Render( const Vector2& size, RenderBehaviour behaviour = RENDER_TEXT_AND_STYLES, bool ignoreHorizontalAlignment = false, Pixel::Format pixelFormat = Pixel::RGBA8888 );
+  PixelData Render( const Vector2& size );
 
 private:
   /**
 
 private:
   /**
@@ -124,46 +92,6 @@ private:
   // Declared private and left undefined to avoid copies.
   Typesetter& operator=( const Typesetter& handle );
 
   // Declared private and left undefined to avoid copies.
   Typesetter& operator=( const Typesetter& handle );
 
-  /**
-   * @brief Create the image buffer for the given range of the glyphs in the given style.
-   *
-   * Does the following operations:
-   * - Retrieves the data buffers from the text model.
-   * - Creates the pixel data used to generate the final image with the given size.
-   * - Traverse the visible glyphs, retrieve their bitmaps and compose the final pixel data.
-   *
-   * @param[in] bufferWidth The width of the image buffer.
-   * @param[in] bufferHeight The height of the image buffer.
-   * @param[in] style The style of the text.
-   * @param[in] ignoreHorizontalAlignment Whether to ignore the horizontal alignment, not ignored by default.
-   * @param[in] pixelFormat The format of the pixel in the image that the text is rendered as (i.e. either Pixel::BGRA8888 or Pixel::L8).
-   * @param[in] verticalOffset The vertical offset to be added to the glyph's position.
-   * @param[in] fromGlyphIndex The index of the first glyph within the text to be drawn
-   * @param[in] toGlyphIndex The index of the last glyph within the text to be drawn
-   *
-   * @return An image buffer with the text.
-   */
-  Devel::PixelBuffer CreateImageBuffer( const unsigned int bufferWidth, const unsigned int bufferHeight, Typesetter::Style style, bool ignoreHorizontalAlignment, Pixel::Format pixelFormat, int verticalOffset, TextAbstraction::GlyphIndex fromGlyphIndex, TextAbstraction::GlyphIndex toGlyphIndex );
-
-  /**
-   * @brief Combine the two RGBA image buffers together.
-   *
-   * The top layer buffer will blend over the bottom layer buffer:
-   * - If the pixel is not fully opaque from either buffer, it will be blended with
-   *   the pixel from the other buffer and copied to the combined buffer.
-   * - If the pixels from both buffers are fully opaque, the pixels from the top layer
-   *   buffer will be copied to the combined buffer.
-   *
-   * @param[in] topPixelBuffer The top layer buffer.
-   * @param[in] bottomPixelBuffer The bottom layer buffer.
-   * @param[in] bufferWidth The width of the image buffer.
-   * @param[in] bufferHeight The height of the image buffer.
-   *
-   * @return The combined image buffer with the text.
-   *
-   */
-  Devel::PixelBuffer CombineImageBuffer( Devel::PixelBuffer topPixelBuffer, Devel::PixelBuffer bottomPixelBuffer, const unsigned int bufferWidth, const unsigned int bufferHeightbool );
-
 protected:
 
   /**
 protected:
 
   /**
@@ -174,7 +102,6 @@ protected:
   virtual ~Typesetter();
 
 private:
   virtual ~Typesetter();
 
 private:
-
    ViewModel* mModel;
 };
 
    ViewModel* mModel;
 };
 
index 1dcda36..eb49465 100644 (file)
@@ -86,16 +86,6 @@ const LineRun* const ViewModel::GetLines() const
   return mModel->GetLines();
 }
 
   return mModel->GetLines();
 }
 
-Length ViewModel::GetNumberOfScripts() const
-{
-  return mModel->GetNumberOfScripts();
-}
-
-const ScriptRun* const ViewModel::GetScriptRuns() const
-{
-  return mModel->GetScriptRuns();
-}
-
 Length ViewModel::GetNumberOfGlyphs() const
 {
   if( mIsTextElided && mModel->IsTextElideEnabled() )
 Length ViewModel::GetNumberOfGlyphs() const
 {
   if( mIsTextElided && mModel->IsTextElideEnabled() )
@@ -153,41 +143,6 @@ const Vector4& ViewModel::GetDefaultColor() const
   return mModel->GetDefaultColor();
 }
 
   return mModel->GetDefaultColor();
 }
 
-const Vector2& ViewModel::GetShadowOffset() const
-{
-  return mModel->GetShadowOffset();
-}
-
-const Vector4& ViewModel::GetShadowColor() const
-{
-  return mModel->GetShadowColor();
-}
-
-const Vector4& ViewModel::GetUnderlineColor() const
-{
-  return mModel->GetUnderlineColor();
-}
-
-bool ViewModel::IsUnderlineEnabled() const
-{
-  return mModel->IsUnderlineEnabled();
-}
-
-float ViewModel::GetUnderlineHeight() const
-{
-  return mModel->GetUnderlineHeight();
-}
-
-Length ViewModel::GetNumberOfUnderlineRuns() const
-{
-  return mModel->GetNumberOfUnderlineRuns();
-}
-
-void ViewModel::GetUnderlineRuns( GlyphRun* underlineRuns, UnderlineRunIndex index, Length numberOfRuns ) const
-{
-  mModel->GetUnderlineRuns( underlineRuns, index, numberOfRuns );
-}
-
 void ViewModel::ElideGlyphs()
 {
   mIsTextElided = false;
 void ViewModel::ElideGlyphs()
 {
   mIsTextElided = false;
index e15fa9c..d178577 100644 (file)
@@ -97,16 +97,6 @@ public:
   virtual const LineRun* const GetLines() const;
 
   /**
   virtual const LineRun* const GetLines() const;
 
   /**
-   * @copydoc ModelInterface::GetNumberOfScripts()
-   */
-  virtual Length GetNumberOfScripts() const;
-
-  /**
-   * @copydoc ModelInterface::GetScriptRuns()
-   */
-  virtual const ScriptRun* const GetScriptRuns() const;
-
-  /**
    * @copydoc ModelInterface::GetNumberOfGlyphs()
    */
   virtual Length GetNumberOfGlyphs() const;
    * @copydoc ModelInterface::GetNumberOfGlyphs()
    */
   virtual Length GetNumberOfGlyphs() const;
@@ -137,41 +127,6 @@ public:
   virtual const Vector4& GetDefaultColor() const;
 
   /**
   virtual const Vector4& GetDefaultColor() const;
 
   /**
-   * @copydoc ModelInterface::GetShadowOffset()
-   */
-  virtual const Vector2& GetShadowOffset() const;
-
-  /**
-   * @copydoc ModelInterface::GetShadowColor()
-   */
-  virtual const Vector4& GetShadowColor() const;
-
-  /**
-   * @copydoc ModelInterface::GetUnderlineColor()
-   */
-  virtual const Vector4& GetUnderlineColor() const;
-
-  /**
-   * @copydoc ModelInterface::IsUnderlineEnabled()
-   */
-  virtual bool IsUnderlineEnabled() const;
-
-  /**
-   * @copydoc ModelInterface::GetUnderlineHeight()
-   */
-  virtual float GetUnderlineHeight() const;
-
-  /**
-   * @copydoc ModelInterface::GetNumberOfUnderlineRuns()
-   */
-  virtual Length GetNumberOfUnderlineRuns() const;
-
-  /**
-   * @copydoc ModelInterface::GetUnderlineRuns()
-   */
-  virtual void GetUnderlineRuns( GlyphRun* underlineRuns, UnderlineRunIndex index, Length numberOfRuns ) const;
-
-  /**
    * @brief Does the text elide.
    *
    * It stores a copy of the visible glyphs and removes as many glyphs as needed
    * @brief Does the text elide.
    *
    * It stores a copy of the visible glyphs and removes as many glyphs as needed
index 258fea7..7875e5c 100644 (file)
@@ -1757,14 +1757,14 @@ Vector3 Controller::GetNaturalSize()
     mImpl->UpdateModel( onlyOnceOperations );
 
     // Layout the text for the new width.
     mImpl->UpdateModel( onlyOnceOperations );
 
     // Layout the text for the new width.
-    mImpl->mOperationsPending = static_cast<OperationsMask>( mImpl->mOperationsPending | LAYOUT | REORDER );
+    mImpl->mOperationsPending = static_cast<OperationsMask>( mImpl->mOperationsPending | LAYOUT );
 
     // Store the actual control's size to restore later.
     const Size actualControlSize = mImpl->mModel->mVisualModel->mControlSize;
 
     DoRelayout( Size( MAX_FLOAT, MAX_FLOAT ),
                 static_cast<OperationsMask>( onlyOnceOperations |
 
     // Store the actual control's size to restore later.
     const Size actualControlSize = mImpl->mModel->mVisualModel->mControlSize;
 
     DoRelayout( Size( MAX_FLOAT, MAX_FLOAT ),
                 static_cast<OperationsMask>( onlyOnceOperations |
-                                             LAYOUT | REORDER ),
+                                             LAYOUT ),
                 naturalSize.GetVectorXY() );
 
     // Do not do again the only once operations.
                 naturalSize.GetVectorXY() );
 
     // Do not do again the only once operations.
@@ -3694,11 +3694,6 @@ void Controller::ResetScrollPosition()
   }
 }
 
   }
 }
 
-void Controller::SetControlInterface( ControlInterface* controlInterface )
-{
-  mImpl->mControlInterface = controlInterface;
-}
-
 bool Controller::ShouldClearFocusOnEscape() const
 {
   return mImpl->mShouldClearFocusOnEscape;
 bool Controller::ShouldClearFocusOnEscape() const
 {
   return mImpl->mShouldClearFocusOnEscape;
index 9e193c7..1f64c24 100644 (file)
@@ -999,13 +999,6 @@ public: // Default style & Input style
    */
   const std::string& GetInputOutlineProperties() const;
 
    */
   const std::string& GetInputOutlineProperties() const;
 
-  /**
-   * @brief Set the control's interface.
-   *
-   * @param[in] controlInterface The control's interface.
-   */
-  void SetControlInterface( ControlInterface* controlInterface );
-
 public: // Queries & retrieves.
 
   /**
 public: // Queries & retrieves.
 
   /**
index 38e1fa2..b3eb694 100644 (file)
@@ -24,7 +24,6 @@
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/layouts/layout-alignment.h>
 #include <dali-toolkit/internal/text/line-run.h>
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/layouts/layout-alignment.h>
 #include <dali-toolkit/internal/text/line-run.h>
-#include <dali-toolkit/internal/text/script-run.h>
 #include <dali-toolkit/internal/text/text-definitions.h>
 
 namespace Dali
 #include <dali-toolkit/internal/text/text-definitions.h>
 
 namespace Dali
@@ -105,20 +104,6 @@ public:
   virtual const LineRun* const GetLines() const = 0;
 
   /**
   virtual const LineRun* const GetLines() const = 0;
 
   /**
-   * @brief Retrieves the number of script runs.
-   *
-   * @return The number of script runs.
-   */
-  virtual Length GetNumberOfScripts() const = 0;
-
-  /**
-   * @brief Retrieves the script runs.
-   *
-   * @return A pointer to the vector with the runs of characters with the same script..
-   */
-  virtual const ScriptRun* const GetScriptRuns() const = 0;
-
-  /**
    * @brief Retrieves the number of laid-out glyphs.
    *
    * @return The number of laid-out glyphs.
    * @brief Retrieves the number of laid-out glyphs.
    *
    * @return The number of laid-out glyphs.
@@ -159,57 +144,6 @@ public:
    * @return The default color.
    */
   virtual const Vector4& GetDefaultColor() const = 0;
    * @return The default color.
    */
   virtual const Vector4& GetDefaultColor() const = 0;
-
-  /**
-   * @brief Retrieves the shadow offset, 0 indicates no shadow.
-   *
-   * @return The shadow offset.
-   */
-  virtual const Vector2& GetShadowOffset() const = 0;
-
-  /**
-   * @brief Retrieves the shadow color.
-   *
-   * @return The shadow color.
-   */
-  virtual const Vector4& GetShadowColor() const = 0;
-
-  /**
-   * @brief Retrieves the underline color.
-   *
-   * @return The underline color.
-   */
-  virtual const Vector4& GetUnderlineColor() const = 0;
-
-  /**
-   * @brief Returns whether underline is enabled or not.
-   *
-   * @return The underline state.
-   */
-  virtual bool IsUnderlineEnabled() const = 0;
-
-  /**
-   * @brief Retrieves the underline height override
-   *
-   * @return Returns the override height for an underline, 0 indicates that adaptor will determine the height
-   */
-  virtual float GetUnderlineHeight() const = 0;
-
-  /**
-   * @brief Retrieves the number of underline runs.
-   *
-   * @return The number of underline runs.
-   */
-  virtual Length GetNumberOfUnderlineRuns() const = 0;
-
-  /**
-   * @brief Retrieves the underline runs.
-   *
-   * @param[out] underlineRuns Pointer to a buffer where the underline runs are copied.
-   * @param[in] index Index of the first underline run to be copied.
-   * @param[in] numberOfRuns Number of underline runs to be copied.
-   */
-  virtual void GetUnderlineRuns( GlyphRun* underlineRuns, UnderlineRunIndex index, Length numberOfRuns ) const = 0;
 };
 
 } // namespace Text
 };
 
 } // namespace Text
index 2c00cf8..95f9514 100644 (file)
@@ -72,16 +72,6 @@ const LineRun* const Model::GetLines() const
   return mVisualModel->mLines.Begin();
 }
 
   return mVisualModel->mLines.Begin();
 }
 
-Length Model::GetNumberOfScripts() const
-{
-  return mLogicalModel->mScriptRuns.Count();
-}
-
-const ScriptRun* const Model::GetScriptRuns() const
-{
-  return mLogicalModel->mScriptRuns.Begin();
-}
-
 Length Model::GetNumberOfGlyphs() const
 {
   return mVisualModel->mGlyphs.Count();
 Length Model::GetNumberOfGlyphs() const
 {
   return mVisualModel->mGlyphs.Count();
@@ -112,41 +102,6 @@ const Vector4& Model::GetDefaultColor() const
   return mVisualModel->mTextColor;
 }
 
   return mVisualModel->mTextColor;
 }
 
-const Vector2& Model::GetShadowOffset() const
-{
-  return mVisualModel->mShadowOffset;
-}
-
-const Vector4& Model::GetShadowColor() const
-{
-  return mVisualModel->mShadowColor;
-}
-
-const Vector4& Model::GetUnderlineColor() const
-{
-  return mVisualModel->GetUnderlineColor();
-}
-
-bool Model::IsUnderlineEnabled() const
-{
-  return mVisualModel->IsUnderlineEnabled();
-}
-
-float Model::GetUnderlineHeight() const
-{
-  return mVisualModel->GetUnderlineHeight();
-}
-
-Length Model::GetNumberOfUnderlineRuns() const
-{
-  return mVisualModel->GetNumberOfUnderlineRuns();
-}
-
-void Model::GetUnderlineRuns( GlyphRun* underlineRuns, UnderlineRunIndex index, Length numberOfRuns ) const
-{
-  mVisualModel->GetUnderlineRuns( underlineRuns, index, numberOfRuns );
-}
-
 Model::Model()
 : mLogicalModel(),
   mVisualModel(),
 Model::Model()
 : mLogicalModel(),
   mVisualModel(),
index a7b0bb8..4256421 100644 (file)
@@ -100,16 +100,6 @@ public:
   virtual const LineRun* const GetLines() const;
 
   /**
   virtual const LineRun* const GetLines() const;
 
   /**
-   * @copydoc ModelInterface::GetNumberOfScripts()
-   */
-  virtual Length GetNumberOfScripts() const;
-
-  /**
-   * @copydoc ModelInterface::GetScriptRuns()
-   */
-  virtual const ScriptRun* const GetScriptRuns() const;
-
-  /**
    * @copydoc ModelInterface::GetNumberOfGlyphs()
    */
   virtual Length GetNumberOfGlyphs() const;
    * @copydoc ModelInterface::GetNumberOfGlyphs()
    */
   virtual Length GetNumberOfGlyphs() const;
@@ -139,41 +129,6 @@ public:
    */
   virtual const Vector4& GetDefaultColor() const;
 
    */
   virtual const Vector4& GetDefaultColor() const;
 
-  /**
-   * @copydoc ModelInterface::GetShadowOffset()
-   */
-  virtual const Vector2& GetShadowOffset() const;
-
-  /**
-   * @copydoc ModelInterface::GetShadowColor()
-   */
-  virtual const Vector4& GetShadowColor() const;
-
-  /**
-   * @copydoc ModelInterface::GetUnderlineColor()
-   */
-  virtual const Vector4& GetUnderlineColor() const;
-
-  /**
-   * @copydoc ModelInterface::IsUnderlineEnabled()
-   */
-  virtual bool IsUnderlineEnabled() const;
-
-  /**
-   * @copydoc ModelInterface::GetUnderlineHeight()
-   */
-  virtual float GetUnderlineHeight() const;
-
-  /**
-   * @copydoc ModelInterface::GetNumberOfUnderlineRuns()
-   */
-  virtual Length GetNumberOfUnderlineRuns() const;
-
-  /**
-   * @copydoc ModelInterface::GetUnderlineRuns()
-   */
-  virtual void GetUnderlineRuns( GlyphRun* underlineRuns, UnderlineRunIndex index, Length numberOfRuns ) const;
-
 private: // Private contructors & copy operator.
 
   /**
 private: // Private contructors & copy operator.
 
   /**
index b109661..590f919 100644 (file)
 
 // EXTERNAL INCLUDES
 #include <dali/public-api/common/stage.h>
 
 // EXTERNAL INCLUDES
 #include <dali/public-api/common/stage.h>
+#include <dali/public-api/images/frame-buffer-image.h>
+#include <dali/public-api/render-tasks/render-task-list.h>
+#include <dali/public-api/rendering/geometry.h>
+#include <dali/public-api/rendering/renderer.h>
+#include <dali/public-api/rendering/sampler.h>
+#include <dali/public-api/rendering/shader.h>
+#include <dali/devel-api/images/texture-set-image.h>
 #include <dali/integration-api/debug.h>
 
 // INTERNAL INCLUDES
 #include <dali/integration-api/debug.h>
 
 // INTERNAL INCLUDES
@@ -44,41 +51,30 @@ const char* VERTEX_SHADER_SCROLL = DALI_COMPOSE_SHADER(
   attribute mediump vec2 aPosition;\n
   varying highp vec2 vTexCoord;\n
   varying highp float vRatio;\n
   attribute mediump vec2 aPosition;\n
   varying highp vec2 vTexCoord;\n
   varying highp float vRatio;\n
-  uniform mediump vec3 uSize;\n
-  uniform mediump float uDelta;\n
-  uniform mediump vec2 uTextureSize;\n
-  uniform mediump float uGap;\n
-  uniform mediump float uHorizontalAlign;\n
-  uniform mediump float uVerticalAlign;\n
-  \n
   uniform mediump mat4 uModelMatrix;\n
   uniform mediump mat4 uViewMatrix;\n
   uniform mediump mat4 uProjection;\n
   uniform mediump mat4 uModelMatrix;\n
   uniform mediump mat4 uViewMatrix;\n
   uniform mediump mat4 uProjection;\n
+  uniform mediump vec3 uSize;\n
+  uniform mediump float uDelta;\n
+  uniform mediump vec2 uTextureSize;
+  uniform mediump float uGap;\n
+  uniform mediump float uAlign;\n
   \n
   \n
-  //Visual size and offset
-  uniform mediump vec2 offset;\n
-  uniform mediump vec2 size;\n
-  uniform mediump vec4 offsetSizeMode;\n
-  uniform mediump vec2 origin;\n
-  uniform mediump vec2 anchorPoint;\n
-
   void main()\n
   {\n
   void main()\n
   {\n
-    mediump vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy );\n
-    mediump vec2 visualSize = mix( uSize.xy * size, size, offsetSizeMode.zw );\n
-    \n
-    mediump float smallTextPadding = max( visualSize.x - uTextureSize.x, 0. );\n
-    mediump float gap = max( uGap, smallTextPadding );\n
-    mediump float delta = floor ( uDelta ) + 0.5;\n
-    vTexCoord.x = ( delta + uHorizontalAlign * ( uTextureSize.x - visualSize.x ) + floor( aPosition.x * visualSize.x ) + 0.5 - gap * 0.5 ) / ( uTextureSize.x + gap ) + 0.5;\n
-    vTexCoord.y = ( uVerticalAlign * ( uTextureSize.y - visualSize.y ) + floor( aPosition.y * visualSize.y ) + 0.5 ) / ( uTextureSize.y ) + 0.5;\n
-    vRatio = uTextureSize.x / ( uTextureSize.x + gap );\n
-    \n
-    mediump vec4 vertexPosition = vec4( floor( ( aPosition + anchorPoint ) * visualSize + ( visualOffset + origin ) * uSize.xy ), 0.0, 1.0 );\n
-    mediump vec4 nonAlignedVertex = uViewMatrix * uModelMatrix * vertexPosition;\n
-    mediump vec4 pixelAlignedVertex = vec4 ( floor( nonAlignedVertex.xyz ), 1.0 );\n
-    \n
-    gl_Position = uProjection * pixelAlignedVertex;\n
+    {\n
+      highp vec4 vertexPosition = vec4(aPosition*uSize.xy, 0.0, 1.0);\n
+      vertexPosition = uViewMatrix *  uModelMatrix  * vertexPosition ;\n
+      vertexPosition.x = floor( vertexPosition.x ) + 0.5;
+      vertexPosition.y = floor( vertexPosition.y ) + 0.5;
+      float smallTextPadding = max(uSize.x - uTextureSize.x, 0. );\n
+      float gap = max( uGap, smallTextPadding );\n
+      float delta = floor ( uDelta ) + 0.5;
+      vTexCoord.x = ( delta  + ( uAlign * ( uTextureSize.x - uSize.x ) ) + (  aPosition.x * uSize.x ) )/ ( uTextureSize.x + gap );\n
+      vTexCoord.y = ( 0.5 + floor(  aPosition.y * uSize.y ) )/ ( uTextureSize.y ) ;\n
+      vRatio = uTextureSize.x / ( uTextureSize.x + gap );\n
+      gl_Position = uProjection * vertexPosition;
+    }\n
   }\n
 );
 
   }\n
 );
 
@@ -92,7 +88,7 @@ const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
     highp vec2 texCoord;\n
     texCoord.y = vTexCoord.y;\n
     texCoord.x = fract( vTexCoord.x ) / vRatio;\n
     highp vec2 texCoord;\n
     texCoord.y = vTexCoord.y;\n
     texCoord.x = fract( vTexCoord.x ) / vRatio;\n
-    if ( texCoord.x > 1.0 || texCoord.y > 1.0 )\n
+    if ( texCoord.x > 1.0 )\n
       discard;\n
     \n
     gl_FragColor = texture2D( sTexture, texCoord );\n
       discard;\n
     \n
     gl_FragColor = texture2D( sTexture, texCoord );\n
@@ -100,46 +96,146 @@ const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
 );
 
 /**
 );
 
 /**
- * @brief How the text should be aligned horizontally when scrolling the text.
+ * @brief How the text should be aligned when scrolling the text.
  *
  *
- * -0.5f aligns the text to the left, 0.0f aligns the text to the center, 0.5f aligns the text to the right.
- * The final alignment depends on two factors:
+ * 0.0f aligns the text to the left, 1.0f aligns the text to the right.
+ * The final alignment depends on three factors:
  *   1) The alignment value of the text label (Use Text::Layout::HorizontalAlignment enumerations).
  *   2) The text direction, i.e. whether it's LTR or RTL (0 = LTR, 1 = RTL).
  *   1) The alignment value of the text label (Use Text::Layout::HorizontalAlignment enumerations).
  *   2) The text direction, i.e. whether it's LTR or RTL (0 = LTR, 1 = RTL).
+ *   3) Whether the text is greater than the size of the control ( 0 = Text width <= Control width, 1 = Text width > Control width ).
  */
  */
-const float HORIZONTAL_ALIGNMENT_TABLE[ Text::Layout::HORIZONTAL_ALIGN_COUNT ][ 2 ] =
+const float ALIGNMENT_TABLE[ Text::Layout::HORIZONTAL_ALIGN_COUNT ][ 2 ][ 2 ] =
 {
   // HORIZONTAL_ALIGN_BEGIN
   {
 {
   // HORIZONTAL_ALIGN_BEGIN
   {
-    -0.5f, // LTR
-    0.5f   // RTL
+    { // LTR
+      0.0f, // Text width <= Control width
+      0.0f  // Text width >  Control width
+    },
+    { // RTL
+      1.0f, // Text width <= Control width
+      1.0f  // Text width >  Control width
+    }
   },
 
   // HORIZONTAL_ALIGN_CENTER
   {
   },
 
   // HORIZONTAL_ALIGN_CENTER
   {
-    0.0f,  // LTR
-    0.0f   // RTL
+    { // LTR
+      0.5f, // Text width <= Control width
+      0.0f  // Text width >  Control width
+    },
+    { // RTL
+      0.5f, // Text width <= Control width
+      1.0f  // Text width >  Control width
+    }
   },
 
   // HORIZONTAL_ALIGN_END
   {
   },
 
   // HORIZONTAL_ALIGN_END
   {
-    0.5f,  // LTR
-    -0.5f  // RTL
+    { // LTR
+      1.0f, // Text width <= Control width
+      0.0f  // Text width >  Control width
+    },
+    { // RTL
+      0.0f, // Text width <= Control width
+      1.0f  // Text width >  Control width
+    }
   }
 };
 
 /**
   }
 };
 
 /**
- * @brief How the text should be aligned vertically when scrolling the text.
+ * @brief Create and set up a camera for the render task to use
  *
  *
- * -0.5f aligns the text to the top, 0.0f aligns the text to the center, 0.5f aligns the text to the bottom.
- * The alignment depends on the alignment value of the text label (Use Text::Layout::VerticalAlignment enumerations).
+ * @param[in] sizeOfTarget size of the source camera to look at
+ * @param[out] offscreenCamera custom camera
  */
  */
-const float VERTICAL_ALIGNMENT_TABLE[ Text::Layout::VERTICAL_ALIGN_COUNT ] =
+void CreateCameraActor( const Size& sizeOfTarget, CameraActor& offscreenCamera )
 {
 {
-  -0.5f, // VERTICAL_ALIGN_TOP
-  0.0f,  // VERTICAL_ALIGN_CENTER
-  0.5f   // VERTICAL_ALIGN_BOTTOM
-};
+  offscreenCamera = CameraActor::New();
+  offscreenCamera.SetOrthographicProjection( sizeOfTarget );
+  offscreenCamera.SetInvertYAxis( true );
+}
+
+/**
+ * @brief Create a render task
+ *
+ * @param[in] sourceActor actor to be used as source
+ * @param[in] cameraActor camera looking at source
+ * @param[in] offscreenTarget resulting image from render task
+ * @param[out] renderTask render task that has been setup
+ */
+void CreateRenderTask( Actor sourceActor, CameraActor cameraActor , FrameBufferImage offscreenTarget, RenderTask& renderTask )
+{
+  Stage stage = Stage::GetCurrent();
+  RenderTaskList taskList = stage.GetRenderTaskList();
+  renderTask = taskList.CreateTask();
+  renderTask.SetSourceActor( sourceActor );
+  renderTask.SetExclusive( true );
+  renderTask.SetInputEnabled( false );
+  renderTask.SetClearEnabled( true );
+  renderTask.SetCameraActor( cameraActor );
+  renderTask.SetTargetFrameBuffer( offscreenTarget );
+  renderTask.SetClearColor( Color::TRANSPARENT );
+  renderTask.SetCullMode( false );
+}
+
+/**
+ * @brief Create quad geometry for the mesh
+ *
+ * @param[out] geometry quad geometry that can be used for a mesh
+ */
+void CreateGeometry( Geometry& geometry )
+{
+  struct QuadVertex { Vector2 position;  };
+
+  QuadVertex quadVertexData[4] =
+  {
+      { Vector2( 0.0f, 0.0f) },
+      { Vector2( 1.0f, 0.0f) },
+      { Vector2( 0.0f, 1.0f) },
+      { Vector2( 1.0f, 1.0f) },
+  };
+
+  const unsigned short indices[6] =
+  {
+     3,1,0,0,2,3
+  };
+
+  Property::Map quadVertexFormat;
+  quadVertexFormat["aPosition"] = Property::VECTOR2;
+  PropertyBuffer quadVertices = PropertyBuffer::New( quadVertexFormat );
+  quadVertices.SetData(quadVertexData, 4 );
+
+  geometry = Geometry::New();
+  geometry.AddVertexBuffer( quadVertices );
+  geometry.SetIndexBuffer( indices, sizeof(indices)/sizeof(indices[0]) );
+}
+
+
+/**
+ * @brief Create a renderer
+ *
+ * @param[in] frameBufferImage texture to be used
+ * @param[out] renderer mesh renderer using the supplied texture
+ */
+void CreateRenderer( FrameBufferImage frameBufferImage, Dali::Renderer& renderer )
+{
+  Shader shader = Shader::New( VERTEX_SHADER_SCROLL , FRAGMENT_SHADER, Shader::Hint::NONE );
+
+  Sampler sampler = Sampler::New();
+  sampler.SetFilterMode(FilterMode::LINEAR, FilterMode::LINEAR );
+
+  TextureSet textureSet = TextureSet::New();
+  TextureSetImage( textureSet, 0u, frameBufferImage );
+  textureSet.SetSampler( 0u, sampler );
+
+  Geometry meshGeometry;
+  CreateGeometry( meshGeometry );
+
+  renderer = Renderer::New( meshGeometry, shader );
+  renderer.SetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, true );
+  renderer.SetTextures( textureSet );
+}
 
 } // namespace
 
 
 } // namespace
 
@@ -215,6 +311,7 @@ void TextScroller::StopScrolling()
       case DevelTextLabel::AutoScrollStopMode::IMMEDIATE:
       {
         mScrollAnimation.Stop();
       case DevelTextLabel::AutoScrollStopMode::IMMEDIATE:
       {
         mScrollAnimation.Stop();
+        CleanUp();
         mScrollerInterface.ScrollingFinished();
         break;
       }
         mScrollerInterface.ScrollingFinished();
         break;
       }
@@ -236,28 +333,38 @@ DevelTextLabel::AutoScrollStopMode::Type TextScroller::GetStopMode() const
   return mStopMode;
 }
 
   return mStopMode;
 }
 
-TextScroller::TextScroller( ScrollerInterface& scrollerInterface )
-: mScrollerInterface( scrollerInterface ),
-  mScrollDeltaIndex( Property::INVALID_INDEX ),
-  mScrollSpeed( MINIMUM_SCROLL_SPEED ),
-  mLoopCount( 1 ),
-  mLoopDelay( 0.0f ),
-  mWrapGap( 0.0f ),
-  mStopMode( DevelTextLabel::AutoScrollStopMode::FINISH_LOOP )
+Actor TextScroller::GetSourceCamera() const
+{
+  return mOffscreenCameraActor;
+}
+
+Actor TextScroller::GetScrollingText() const
+{
+  return mScrollingTextActor;
+}
+
+TextScroller::TextScroller( ScrollerInterface& scrollerInterface ) : mScrollerInterface( scrollerInterface ),
+                            mScrollDeltaIndex( Property::INVALID_INDEX ),
+                            mScrollSpeed( MINIMUM_SCROLL_SPEED ),
+                            mLoopCount( 1 ),
+                            mLoopDelay( 0.0f ),
+                            mWrapGap( 0.0f ),
+                            mStopMode( DevelTextLabel::AutoScrollStopMode::FINISH_LOOP )
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller Default Constructor\n" );
 }
 
 TextScroller::~TextScroller()
 {
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller Default Constructor\n" );
 }
 
 TextScroller::~TextScroller()
 {
+  CleanUp();
 }
 
 }
 
-void TextScroller::SetParameters( Actor scrollingTextActor, Renderer renderer, TextureSet textureSet, const Size& controlSize, const Size& textNaturalSize, CharacterDirection direction, Layout::HorizontalAlignment horizontalAlignment, Layout::VerticalAlignment verticalAlignment )
+void TextScroller::SetParameters( Actor sourceActor, const Size& controlSize, const Size& offScreenSize, CharacterDirection direction, float alignmentOffset, Layout::HorizontalAlignment horizontalAlignment )
 {
 {
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetParameters controlSize[%f,%f] offscreenSize[%f,%f] direction[%d]\n",
-                 controlSize.x, controlSize.y, textNaturalSize.x, textNaturalSize.y, direction );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetParameters controlSize[%f,%f] offscreenSize[%f,%f] direction[%d] alignmentOffset[%f]\n",
+                 controlSize.x, controlSize.y, offScreenSize.x, offScreenSize.y, direction, alignmentOffset );
 
 
-  mRenderer = renderer;
+  CleanUp(); //  If already scrolling then restart with new parameters
 
   float animationProgress = 0.0f;
   int   remainedLoop = mLoopCount;
 
   float animationProgress = 0.0f;
   int   remainedLoop = mLoopCount;
@@ -274,69 +381,114 @@ void TextScroller::SetParameters( Actor scrollingTextActor, Renderer renderer, T
       }
     }
     mScrollAnimation.Clear();
       }
     }
     mScrollAnimation.Clear();
+  }
+
+  FrameBufferImage offscreenRenderTargetForText = FrameBufferImage::New( offScreenSize.width, offScreenSize.height, Pixel::RGBA8888 );
+  Renderer renderer;
 
 
-    // Reset to the original shader and texture before scrolling
-    mRenderer.SetShader(mShader);
-    mRenderer.SetTextures( mTextureSet );
+  CreateCameraActor( offScreenSize, mOffscreenCameraActor );
+  CreateRenderer( offscreenRenderTargetForText, renderer );
+  CreateRenderTask( sourceActor, mOffscreenCameraActor, offscreenRenderTargetForText, mRenderTask );
+
+  float xPosition = 0.0f;
+  switch( horizontalAlignment )
+  {
+    case Layout::HORIZONTAL_ALIGN_BEGIN:
+    {
+      // Reposition camera to match alignment of target, RTL text has direction=true
+      if ( direction )
+      {
+        xPosition = alignmentOffset + offScreenSize.width * 0.5f;
+      }
+      else
+      {
+        xPosition = offScreenSize.width * 0.5f;
+      }
+      break;
+    }
+
+    case Layout::HORIZONTAL_ALIGN_CENTER:
+    {
+      xPosition = controlSize.width * 0.5f;
+      break;
+    }
+
+    case Layout::HORIZONTAL_ALIGN_END:
+    {
+      // Reposition camera to match alignment of target, RTL text has direction=true
+      if ( direction )
+      {
+        xPosition = offScreenSize.width * 0.5f;
+      }
+      else
+      {
+        xPosition = alignmentOffset + offScreenSize.width * 0.5f;
+      }
+      break;
+    }
   }
 
   }
 
-  mShader = mRenderer.GetShader();
-  mTextureSet = mRenderer.GetTextures();
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetParameters xPosition[%f]\n", xPosition );
 
 
-  // Set the shader and texture for scrolling
-  Shader shader = Shader::New( VERTEX_SHADER_SCROLL, FRAGMENT_SHADER, Shader::Hint::NONE );
-  mRenderer.SetShader( shader );
-  mRenderer.SetTextures( textureSet );
+  mOffscreenCameraActor.SetX( xPosition );
+  mOffscreenCameraActor.SetY( offScreenSize.height * 0.5f );
 
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetParameters mWrapGap[%f]\n", mWrapGap );
 
 
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetParameters mWrapGap[%f]\n", mWrapGap );
 
-  const float horizontalAlign = HORIZONTAL_ALIGNMENT_TABLE[ horizontalAlignment ][ direction ];
-  const float verticalAlign = VERTICAL_ALIGNMENT_TABLE[ verticalAlignment ];
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetParameters horizontalAlign[%f], verticalAlign[%f]\n", horizontalAlign, verticalAlign );
+  const float align = ALIGNMENT_TABLE[ horizontalAlignment ][ direction ][ offScreenSize.width > controlSize.width ];
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetParameters align[%f]\n", align );
 
 
-  scrollingTextActor.RegisterProperty( "uTextureSize", textNaturalSize );
-  scrollingTextActor.RegisterProperty( "uHorizontalAlign", horizontalAlign );
-  scrollingTextActor.RegisterProperty( "uVerticalAlign", verticalAlign );
-  scrollingTextActor.RegisterProperty( "uGap", mWrapGap );
-  mScrollDeltaIndex = scrollingTextActor.RegisterProperty( "uDelta", 0.0f );
+  mScrollingTextActor = Actor::New();
+  mScrollingTextActor.AddRenderer( renderer );
+  mScrollingTextActor.RegisterProperty( "uTextureSize", offScreenSize );
+  mScrollingTextActor.RegisterProperty( "uAlign", align );
+  mScrollingTextActor.RegisterProperty( "uGap", mWrapGap );
+  mScrollingTextActor.SetSize( controlSize.width, std::min( offScreenSize.height, controlSize.height ) );
+  mScrollDeltaIndex = mScrollingTextActor.RegisterProperty( "uDelta", 0.0f );
 
 
-  float scrollAmount = std::max( textNaturalSize.width + mWrapGap, controlSize.width );
+  float scrollAmount = std::max( offScreenSize.width + mWrapGap, controlSize.width );
   float scrollDuration =  scrollAmount / mScrollSpeed;
 
   if ( direction  )
   {
   float scrollDuration =  scrollAmount / mScrollSpeed;
 
   if ( direction  )
   {
-     scrollAmount = -scrollAmount; // reverse direction of scrolling
+     scrollAmount = -scrollAmount; // reverse direction of scrollung
   }
 
   }
 
-  StartScrolling( scrollingTextActor, scrollAmount, scrollDuration, remainedLoop );
+  StartScrolling( scrollAmount, scrollDuration, remainedLoop );
   mScrollAnimation.SetCurrentProgress(animationProgress);
 }
 
 void TextScroller::AutoScrollAnimationFinished( Dali::Animation& animation )
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::AutoScrollAnimationFinished\n" );
   mScrollAnimation.SetCurrentProgress(animationProgress);
 }
 
 void TextScroller::AutoScrollAnimationFinished( Dali::Animation& animation )
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::AutoScrollAnimationFinished\n" );
+  CleanUp();
   mScrollerInterface.ScrollingFinished();
   mScrollerInterface.ScrollingFinished();
-
-  // Revert to the original shader and texture after scrolling
-  mRenderer.SetShader(mShader);
-  if ( mTextureSet )
-  {
-    mRenderer.SetTextures( mTextureSet );
-  }
 }
 
 }
 
-void TextScroller::StartScrolling( Actor scrollingTextActor, float scrollAmount, float scrollDuration, int loopCount )
+void TextScroller::StartScrolling( float scrollAmount, float scrollDuration, int loopCount )
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::StartScrolling scrollAmount[%f] scrollDuration[%f], loop[%d] speed[%d]\n", scrollAmount, scrollDuration, loopCount, mScrollSpeed );
 
   mScrollAnimation = Animation::New( scrollDuration );
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::StartScrolling scrollAmount[%f] scrollDuration[%f], loop[%d] speed[%d]\n", scrollAmount, scrollDuration, loopCount, mScrollSpeed );
 
   mScrollAnimation = Animation::New( scrollDuration );
-  mScrollAnimation.AnimateTo( Property( scrollingTextActor, mScrollDeltaIndex ), scrollAmount, TimePeriod( mLoopDelay, scrollDuration ) );
+  mScrollAnimation.AnimateTo( Property( mScrollingTextActor, mScrollDeltaIndex ), scrollAmount, TimePeriod( mLoopDelay, scrollDuration ) );
   mScrollAnimation.SetEndAction( Animation::Discard );
   mScrollAnimation.SetLoopCount( loopCount );
   mScrollAnimation.FinishedSignal().Connect( this, &TextScroller::AutoScrollAnimationFinished );
   mScrollAnimation.Play();
 }
 
   mScrollAnimation.SetEndAction( Animation::Discard );
   mScrollAnimation.SetLoopCount( loopCount );
   mScrollAnimation.FinishedSignal().Connect( this, &TextScroller::AutoScrollAnimationFinished );
   mScrollAnimation.Play();
 }
 
+void TextScroller::CleanUp()
+{
+  if ( Stage::IsInstalled() )
+  {
+    Stage stage = Stage::GetCurrent();
+    RenderTaskList taskList = stage.GetRenderTaskList();
+    UnparentAndReset( mScrollingTextActor );
+    UnparentAndReset( mOffscreenCameraActor );
+    taskList.RemoveTask( mRenderTask );
+  }
+}
+
 } // namespace Text
 
 } // namespace Toolkit
 } // namespace Text
 
 } // namespace Toolkit
index b8dc10f..2d611bb 100644 (file)
@@ -22,7 +22,6 @@
 #include <dali/public-api/actors/camera-actor.h>
 #include <dali/public-api/animation/animation.h>
 #include <dali/public-api/render-tasks/render-task.h>
 #include <dali/public-api/actors/camera-actor.h>
 #include <dali/public-api/animation/animation.h>
 #include <dali/public-api/render-tasks/render-task.h>
-#include <dali/public-api/rendering/renderer.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/devel-api/controls/text-controls/text-label-devel.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/devel-api/controls/text-controls/text-label-devel.h>
@@ -61,16 +60,14 @@ public:
   /**
    * @brief Set parameters relating to source required for scrolling
    *
   /**
    * @brief Set parameters relating to source required for scrolling
    *
-   * @param[in] scrollingTextActor actor containing the text to be scrolled
-   * @param[in] renderer renderer to render the text
-   * @param[in] textureSet texture of the text to be scrolled
+   * @param[in] sourceActor source actor to be scrolled
    * @param[in] controlSize size of the control to scroll within
    * @param[in] controlSize size of the control to scroll within
-   * @param[in] textNaturalSize natural size of the text
+   * @param[in] offScreenSize size of the sourceActor
    * @param[in] direction text direction true for right to left text
    * @param[in] direction text direction true for right to left text
-   * @param[in] horizontalAlignment horizontal alignment of the text
-   * @param[in] verticalAlignment vertical alignment of the text
+   * @param[in] alignmentOffset alignment of source text
+   *
    */
    */
-  void SetParameters( Actor scrollingTextActor, Dali::Renderer renderer, TextureSet textureSet, const Size& controlSize, const Size& offScreenSize, CharacterDirection direction, Layout::HorizontalAlignment horizontalAlignment, Layout::VerticalAlignment verticalAlignment );
+  void SetParameters( Actor sourceActor, const Size& controlSize, const Size& offScreenSize, CharacterDirection direction, float alignmentOffset, Layout::HorizontalAlignment horizontalAlignment );
 
   /**
    * @brief Set the gap distance to elapse before the text wraps around
 
   /**
    * @brief Set the gap distance to elapse before the text wraps around
@@ -137,6 +134,18 @@ public:
    */
   DevelTextLabel::AutoScrollStopMode::Type GetStopMode() const;
 
    */
   DevelTextLabel::AutoScrollStopMode::Type GetStopMode() const;
 
+  /**
+   * @brief Get the camera used to look at source, should be added to the parent of target actor.
+   * @return camera Actor
+   */
+  Actor GetSourceCamera() const;
+
+  /**
+   * @brief Get the resulting scrolling text actor, add to target actor which will show scrolling text
+   * @return mesh Actor
+   */
+  Actor GetScrollingText() const;
+
 private: // Implementation
 
   /**
 private: // Implementation
 
   /**
@@ -163,21 +172,25 @@ private: // Implementation
 
   /**
    * @brief variables required to set up scrolling animation
 
   /**
    * @brief variables required to set up scrolling animation
-   * @param[in] scrollingTextActor actor that shows scrolling text
    * @param[in] scrollAmount distance to animate text for the given duration
    * @param[in] scrollDuration duration of aninmation
    * @param[in] loopCount number of times to loop the scrolling text
    */
    * @param[in] scrollAmount distance to animate text for the given duration
    * @param[in] scrollDuration duration of aninmation
    * @param[in] loopCount number of times to loop the scrolling text
    */
-  void StartScrolling( Actor scrollingTextActor, float scrollAmount, float scrollDuration, int loopCount );
+  void StartScrolling( float scrollAmount, float scrollDuration, int loopCount );
+
+  /**
+   * @brief When scrolling ended, the actors are cleaned up so no longer staged.
+   */
+  void CleanUp();
 
 private:
 
 
 private:
 
+  RenderTask         mRenderTask;               // Renders full text to a FrameBuffer which is then scrolled.
+  CameraActor        mOffscreenCameraActor;     // Camera used by render task
+  Actor              mScrollingTextActor;       // Actor used to show scrolling text
   ScrollerInterface& mScrollerInterface;        // Interface implemented by control that requires scrolling
   Property::Index    mScrollDeltaIndex;         // Property used by shader to represent distance to scroll
   Animation          mScrollAnimation;          // Animation used to update the mScrollDeltaIndex
   ScrollerInterface& mScrollerInterface;        // Interface implemented by control that requires scrolling
   Property::Index    mScrollDeltaIndex;         // Property used by shader to represent distance to scroll
   Animation          mScrollAnimation;          // Animation used to update the mScrollDeltaIndex
-  Dali::Renderer     mRenderer;                 // Renderer used to render the text
-  Shader             mShader;                   // Shader originally used by the renderer while not scrolling
-  TextureSet         mTextureSet;               // Texture originally used by the renderer while not scrolling
 
   int   mScrollSpeed;                                   ///< Speed which text should automatically scroll at
   int   mLoopCount;                                     ///< Number of time the text should scroll
 
   int   mScrollSpeed;                                   ///< Speed which text should automatically scroll at
   int   mLoopCount;                                     ///< Number of time the text should scroll
index 9e8d0be..754b06d 100644 (file)
@@ -384,7 +384,7 @@ Length View::GetNumberOfUnderlineRuns() const
 {
   if( mImpl->mVisualModel )
   {
 {
   if( mImpl->mVisualModel )
   {
-    return mImpl->mVisualModel->GetNumberOfUnderlineRuns();
+    return mImpl->mVisualModel->mUnderlineRuns.Count();
   }
 
   return 0u;
   }
 
   return 0u;
index 1b114c4..2ee0bab 100644 (file)
@@ -390,11 +390,6 @@ float VisualModel::GetUnderlineHeight() const
   return mUnderlineHeight;
 }
 
   return mUnderlineHeight;
 }
 
-Length VisualModel::GetNumberOfUnderlineRuns() const
-{
-  return mUnderlineRuns.Count();
-}
-
 void VisualModel::ClearCaches()
 {
   mCachedLineIndex = 0u;
 void VisualModel::ClearCaches()
 {
   mCachedLineIndex = 0u;
index 6356f32..0874c05 100644 (file)
@@ -280,13 +280,6 @@ public:
    */
   float GetUnderlineHeight() const;
 
    */
   float GetUnderlineHeight() const;
 
-  /**
-   * @brief Retrieves the number of underline runs.
-   *
-   * @return The number of underline runs.
-   */
-  Length GetNumberOfUnderlineRuns() const;
-
 protected:
 
   /**
 protected:
 
   /**
index 2968f07..7ce455e 100644 (file)
 // CLASS HEADER
 #include <dali-toolkit/internal/visuals/text/text-visual.h>
 
 // CLASS HEADER
 #include <dali-toolkit/internal/visuals/text/text-visual.h>
 
-// EXTERNAL INCLUDES
-#include <dali/public-api/animation/constraints.h>
-#include <dali/devel-api/text-abstraction/text-abstraction-definitions.h>
-
 // INTERNAL HEADER
 #include <dali-toolkit/devel-api/visuals/text-visual-properties.h>
 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
 // INTERNAL HEADER
 #include <dali-toolkit/devel-api/visuals/text-visual-properties.h>
 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
@@ -31,8 +27,6 @@
 #include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
 #include <dali-toolkit/internal/text/text-font-style.h>
 #include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
 #include <dali-toolkit/internal/text/text-font-style.h>
-#include <dali-toolkit/internal/text/text-effects-style.h>
-#include <dali-toolkit/internal/text/script-run.h>
 
 namespace Dali
 {
 
 namespace Dali
 {
@@ -55,8 +49,6 @@ const char * const HORIZONTAL_ALIGNMENT_PROPERTY( "horizontalAlignment" );
 const char * const VERTICAL_ALIGNMENT_PROPERTY( "verticalAlignment" );
 const char * const TEXT_COLOR_PROPERTY( "textColor" );
 const char * const ENABLE_MARKUP_PROPERTY( "enableMarkup" );
 const char * const VERTICAL_ALIGNMENT_PROPERTY( "verticalAlignment" );
 const char * const TEXT_COLOR_PROPERTY( "textColor" );
 const char * const ENABLE_MARKUP_PROPERTY( "enableMarkup" );
-const char * const SHADOW_PROPERTY( "shadow" );
-const char * const UNDERLINE_PROPERTY( "underline" );
 
 const Scripting::StringEnum HORIZONTAL_ALIGNMENT_STRING_TABLE[] =
 {
 
 const Scripting::StringEnum HORIZONTAL_ALIGNMENT_STRING_TABLE[] =
 {
@@ -98,14 +90,14 @@ const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
   attribute mediump vec2 aPosition;\n
   uniform mediump mat4 uMvpMatrix;\n
   uniform mediump vec3 uSize;\n
   attribute mediump vec2 aPosition;\n
   uniform mediump mat4 uMvpMatrix;\n
   uniform mediump vec3 uSize;\n
-  uniform mediump vec4 pixelArea;\n
+  uniform mediump vec4 pixelArea;
 
   uniform mediump mat4 uModelMatrix;\n
   uniform mediump mat4 uViewMatrix;\n
   uniform mediump mat4 uProjection;\n
 
   varying mediump vec2 vTexCoord;\n
 
   uniform mediump mat4 uModelMatrix;\n
   uniform mediump mat4 uViewMatrix;\n
   uniform mediump mat4 uProjection;\n
 
   varying mediump vec2 vTexCoord;\n
-
+  \n
   //Visual size and offset
   uniform mediump vec2 offset;\n
   uniform mediump vec2 size;\n
   //Visual size and offset
   uniform mediump vec2 offset;\n
   uniform mediump vec2 size;\n
@@ -131,54 +123,19 @@ const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
   }\n
 );
 
   }\n
 );
 
-const char* FRAGMENT_SHADER_ATLAS_CLAMP_RGBA = 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
-  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
-
-    // 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
-
-    // Draw the text as overlay above the style
-    gl_FragColor = ( textColor + styleTexture * ( 1.0 - textTexture.a ) ) * uColor * vec4( mixColor, opacity );\n
-  }\n
-);
-
-const char* FRAGMENT_SHADER_ATLAS_CLAMP_L8 = 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
-  }\n
+const char* FRAGMENT_SHADER_ATLAS_CLAMP = 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
+      gl_FragColor = texture2D( sTexture, texCoord ) * uColor * vec4( mixColor, opacity );\n
+    }\n
 );
 
 /**
 );
 
 /**
@@ -231,14 +188,6 @@ Dali::Property::Index StringKeyToIndexKey( const std::string& stringKey )
   {
     result = Toolkit::TextVisual::Property::ENABLE_MARKUP;
   }
   {
     result = Toolkit::TextVisual::Property::ENABLE_MARKUP;
   }
-  else if( stringKey == SHADOW_PROPERTY )
-  {
-    result = Toolkit::TextVisual::Property::SHADOW;
-  }
-  else if( stringKey == UNDERLINE_PROPERTY )
-  {
-    result = Toolkit::TextVisual::Property::UNDERLINE;
-  }
 
   return result;
 }
 
   return result;
 }
@@ -310,12 +259,6 @@ void TextVisual::DoCreatePropertyMap( Property::Map& map ) const
   map.Insert( Toolkit::TextVisual::Property::TEXT_COLOR, mController->GetDefaultColor() );
 
   map.Insert( Toolkit::TextVisual::Property::ENABLE_MARKUP, mController->IsMarkupProcessorEnabled() );
   map.Insert( Toolkit::TextVisual::Property::TEXT_COLOR, mController->GetDefaultColor() );
 
   map.Insert( Toolkit::TextVisual::Property::ENABLE_MARKUP, mController->IsMarkupProcessorEnabled() );
-
-  GetShadowProperties( mController, value, Text::EffectStyle::DEFAULT );
-  map.Insert( Toolkit::TextVisual::Property::SHADOW, value );
-
-  GetUnderlineProperties( mController, value, Text::EffectStyle::DEFAULT );
-  map.Insert( Toolkit::TextVisual::Property::UNDERLINE, value );
 }
 
 void TextVisual::DoCreateInstancePropertyMap( Property::Map& map ) const
 }
 
 void TextVisual::DoCreateInstancePropertyMap( Property::Map& map ) const
@@ -331,9 +274,7 @@ void TextVisual::DoCreateInstancePropertyMap( Property::Map& map ) const
 TextVisual::TextVisual( VisualFactoryCache& factoryCache )
 : Visual::Base( factoryCache ),
   mController( Text::Controller::New() ),
 TextVisual::TextVisual( VisualFactoryCache& factoryCache )
 : Visual::Base( factoryCache ),
   mController( Text::Controller::New() ),
-  mTypesetter( Text::Typesetter::New( mController->GetTextModel() ) ),
-  mAnimatableTextColorPropertyIndex( Property::INVALID_INDEX ),
-  mRendererUpdateNeeded( false )
+  mTypesetter( Text::Typesetter::New( mController->GetTextModel() ) )
 {
 }
 
 {
 }
 
@@ -372,29 +313,20 @@ void TextVisual::DoSetOnStage( Actor& actor )
   mControl = actor;
 
   Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY );
   mControl = actor;
 
   Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY );
-  Shader shader = GetTextShader(mFactoryCache, true);
 
 
-  mImpl->mRenderer = Renderer::New( geometry, shader );
-  mImpl->mRenderer.SetProperty( Dali::Renderer::Property::DEPTH_INDEX, Toolkit::DepthIndex::CONTENT );
-
-  const Vector4& defaultColor = mController->GetTextModel()->GetDefaultColor();
-  Dali::Property::Index shaderTextColorIndex = mImpl->mRenderer.RegisterProperty( "uTextColorAnimatable", defaultColor );
-
-  if ( mAnimatableTextColorPropertyIndex != Property::INVALID_INDEX )
+  Shader shader = mFactoryCache.GetShader( VisualFactoryCache::TEXT_SHADER );
+  if( ! shader )
   {
   {
-    // Create constraint for the animatable text's color Property with uTextColorAnimatable in the renderer.
-    if( shaderTextColorIndex != Property::INVALID_INDEX )
-    {
-      Constraint constraint = Constraint::New<Vector4>( mImpl->mRenderer, shaderTextColorIndex, EqualToConstraint() );
-      constraint.AddSource( Source( actor, mAnimatableTextColorPropertyIndex ) );
-      constraint.Apply();
-    }
+    shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_ATLAS_CLAMP );
+    shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
+
+    mFactoryCache.SaveShader( VisualFactoryCache::TEXT_SHADER, shader );
   }
 
   }
 
-  // Renderer needs textures and to be added to control
-  mRendererUpdateNeeded = true;
+  mImpl->mRenderer = Renderer::New( geometry, shader );
+  mImpl->mRenderer.SetProperty( Dali::Renderer::Property::DEPTH_INDEX, Toolkit::DepthIndex::CONTENT );
 
 
-  UpdateRenderer();
+  UpdateRenderer( true ); // Renderer needs textures and to be added to control
 }
 
 void TextVisual::DoSetOffStage( Actor& actor )
 }
 
 void TextVisual::DoSetOffStage( Actor& actor )
@@ -416,7 +348,7 @@ void TextVisual::DoSetOffStage( Actor& actor )
 
 void TextVisual::OnSetTransform()
 {
 
 void TextVisual::OnSetTransform()
 {
-  UpdateRenderer();
+  UpdateRenderer( false );
 }
 
 void TextVisual::DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue )
 }
 
 void TextVisual::DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue )
@@ -491,20 +423,10 @@ void TextVisual::DoSetProperty( Dali::Property::Index index, const Dali::Propert
       }
       break;
     }
       }
       break;
     }
-    case Toolkit::TextVisual::Property::SHADOW:
-    {
-      SetShadowProperties( mController, propertyValue, Text::EffectStyle::DEFAULT );
-      break;
-    }
-    case Toolkit::TextVisual::Property::UNDERLINE:
-    {
-      SetUnderlineProperties( mController, propertyValue, Text::EffectStyle::DEFAULT );
-      break;
-    }
   }
 }
 
   }
 }
 
-void TextVisual::UpdateRenderer()
+void TextVisual::UpdateRenderer( bool initializeRendererAndTexture )
 {
   Actor control = mControl.GetHandle();
   if( !control )
 {
   Actor control = mControl.GetHandle();
   if( !control )
@@ -541,11 +463,8 @@ void TextVisual::UpdateRenderer()
 
   const Text::Controller::UpdateTextType updateTextType = mController->Relayout( relayoutSize );
 
 
   const Text::Controller::UpdateTextType updateTextType = mController->Relayout( relayoutSize );
 
-  if( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType )
-   || mRendererUpdateNeeded )
+  if( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType ) || initializeRendererAndTexture )
   {
   {
-    mRendererUpdateNeeded = false;
-
     // Removes the texture set.
     RemoveTextureSet();
 
     // Removes the texture set.
     RemoveTextureSet();
 
@@ -558,133 +477,39 @@ void TextVisual::UpdateRenderer()
     if( ( relayoutSize.width > Math::MACHINE_EPSILON_1000 ) &&
         ( relayoutSize.height > Math::MACHINE_EPSILON_1000 ) )
     {
     if( ( relayoutSize.width > Math::MACHINE_EPSILON_1000 ) &&
         ( relayoutSize.height > Math::MACHINE_EPSILON_1000 ) )
     {
-      // Check whether it is a markup text with multiple text colors
-      const Vector4* const colorsBuffer = mController->GetTextModel()->GetColors();
-      bool hasMultipleTextColors = ( NULL != colorsBuffer );
-
-      // Check whether the text contains any emoji
-      bool containsEmoji = false;
-
-      Text::ScriptRunIndex numberOfScripts = mController->GetTextModel()->GetNumberOfScripts();
-      const Text::ScriptRun* scripts = mController->GetTextModel()->GetScriptRuns();
-      for ( Text::ScriptRunIndex scriptIndex = 0u; scriptIndex < numberOfScripts; scriptIndex++ )
-      {
-        const Text::ScriptRun& scriptRun = *( scripts + scriptIndex );
-        if( TextAbstraction::EMOJI == scriptRun.script )
-        {
-          containsEmoji = true;
-          break;
-        }
-      }
-
-      // Check whether the text contains any style colors (e.g. underline color, shadow color, etc.)
-      bool shadowEnabled = false;
-      const Vector2& shadowOffset = mController->GetTextModel()->GetShadowOffset();
-      if ( fabsf( shadowOffset.x ) > Math::MACHINE_EPSILON_1 || fabsf( shadowOffset.y ) > Math::MACHINE_EPSILON_1 )
-      {
-        shadowEnabled = true;
-      }
-
-      const bool underlineEnabled = mController->GetTextModel()->IsUnderlineEnabled();
-
-      if ( hasMultipleTextColors || containsEmoji || shadowEnabled || underlineEnabled )
-      {
-        // 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 );
+      PixelData data = mTypesetter->Render( relayoutSize );
 
 
-        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 );
-
-        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() );
+      Vector4 atlasRect = FULL_TEXTURE_RECT;
 
 
-        texture.Upload( data );
+      // Texture set not retrieved from Atlas Manager whilst pixel offset visible.
 
 
-        TextureSet textureSet = TextureSet::New();
-        textureSet.SetTexture( 0u, texture );
+      // 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.
 
 
-        // 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 );
+      Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D,
+                                      data.GetPixelFormat(),
+                                      data.GetWidth(),
+                                      data.GetHeight() );
 
 
-        mImpl->mRenderer.SetTextures( textureSet );
+      texture.Upload( data );
 
 
-        Shader shader = GetTextShader(mFactoryCache, false); // L8 shader
-        mImpl->mRenderer.SetShader(shader);
-      }
+      TextureSet textureSet = TextureSet::New();
+      textureSet.SetTexture( 0u, texture );
 
       mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED;
 
 
       mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED;
 
-      Vector4 atlasRect = FULL_TEXTURE_RECT;
       mImpl->mRenderer.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, atlasRect );
       mImpl->mRenderer.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, atlasRect );
-      mImpl->mRenderer.RegisterProperty( "uHasMultipleTextColors", static_cast<float>( hasMultipleTextColors ) );
-
-      mImpl->mRenderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON);
 
       //Register transform properties
       mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT );
 
 
       //Register transform properties
       mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT );
 
+      // Filter mode needs to be set to nearest to avoid blurry text.
+      Sampler sampler = Sampler::New();
+      sampler.SetFilterMode( FilterMode::NEAREST, FilterMode::NEAREST );
+      textureSet.SetSampler( 0u, sampler );
+
+      mImpl->mRenderer.SetTextures( textureSet );
+
       control.AddRenderer( mImpl->mRenderer );
 
       // Text rendered and ready to display
       control.AddRenderer( mImpl->mRenderer );
 
       // Text rendered and ready to display
@@ -712,33 +537,6 @@ void TextVisual::RemoveTextureSet()
   }
 }
 
   }
 }
 
-Shader TextVisual::GetTextShader( VisualFactoryCache& factoryCache, bool isRgbaTexture )
-{
-  Shader shader;
-  if( isRgbaTexture )
-  {
-    shader = factoryCache.GetShader( VisualFactoryCache::TEXT_SHADER_RGBA );
-    if( !shader )
-    {
-      shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_ATLAS_CLAMP_RGBA );
-      shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
-      factoryCache.SaveShader( VisualFactoryCache::TEXT_SHADER_RGBA, shader );
-    }
-  }
-  else
-  {
-    shader = factoryCache.GetShader( VisualFactoryCache::TEXT_SHADER_L8 );
-    if( !shader )
-    {
-      shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_ATLAS_CLAMP_L8 );
-      shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
-      factoryCache.SaveShader( VisualFactoryCache::TEXT_SHADER_L8, shader );
-    }
-  }
-
-  return shader;
-}
-
 } // namespace Internal
 
 } // namespace Toolkit
 } // namespace Internal
 
 } // namespace Toolkit
index 31353b9..8222276 100644 (file)
@@ -18,9 +18,6 @@
  *
  */
 
  *
  */
 
-// EXTERNAL INCLUDES
-#include <dali/public-api/object/base-object.h>
-
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
 #include <dali-toolkit/internal/text/rendering/text-typesetter.h>
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
 #include <dali-toolkit/internal/text/rendering/text-typesetter.h>
@@ -84,35 +81,6 @@ public:
    */
   static void ConvertStringKeysToIndexKeys( Property::Map& propertyMap );
 
    */
   static void ConvertStringKeysToIndexKeys( Property::Map& propertyMap );
 
-  /**
-   * @brief Retrieve the text's controller.
-   * @param[in] visual The text visual.
-   * @return The text controller
-   */
-  static Text::ControllerPtr GetController( Toolkit::Visual::Base visual )
-  {
-    return GetVisualObject( visual ).mController;
-  };
-
-  /**
-   * @brief Set the index of the animatable text color property.
-   * @param[in] visual The text visual.
-   * @param[in] animatablePropertyIndex The index of the animatable property
-   */
-  static void SetAnimatableTextColorProperty( Toolkit::Visual::Base visual, Property::Index animatablePropertyIndex )
-  {
-    GetVisualObject( visual ).mAnimatableTextColorPropertyIndex = animatablePropertyIndex;
-  };
-
-  /**
-   * @brief Set the flag to trigger the textures to be initialized and renderer to be added to the control.
-   * @param[in] visual The text visual.
-   */
-  static void EnableRendererUpdate( Toolkit::Visual::Base visual )
-  {
-    GetVisualObject( visual ).mRendererUpdateNeeded = true;
-  };
-
 public: // from Visual::Base
 
   /**
 public: // from Visual::Base
 
   /**
@@ -183,37 +151,19 @@ private:
 
   /**
    * @brief Updates the text's renderer.
 
   /**
    * @brief Updates the text's renderer.
+   * @param[in] initializeRendererAndTexture Set flag to true to initialize textures and add renderer to control.
    */
    */
-  void UpdateRenderer();
+  void UpdateRenderer( bool initializeRendererAndTexture );
 
   /**
    * @brief Removes the texture set from the renderer.
    */
   void RemoveTextureSet();
 
 
   /**
    * @brief Removes the texture set from the renderer.
    */
   void RemoveTextureSet();
 
-  /**
-   * 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.
-   */
-  Shader GetTextShader( VisualFactoryCache& factoryCache, bool isRgbaTexture );
-
-  /**
-   * @brief Retrieve the text's controller.
-   * @param[in] visual The text visual.
-   * @return The text controller
-   */
-  static TextVisual& GetVisualObject( Toolkit::Visual::Base visual )
-  {
-    return static_cast<TextVisual&>( visual.GetBaseObject() );
-  };
-
 private:
 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.
-  Property::Index     mAnimatableTextColorPropertyIndex;  ///< The index of animatable text color property registered by the control.
-  bool                mRendererUpdateNeeded:1;            ///< The flag to indicate whether the renderer needs to be updated.
+  Text::ControllerPtr mController; ///< The text's controller.
+  Text::TypesetterPtr mTypesetter; ///< The text's typesetter.
+  WeakHandle<Actor>   mControl;    ///< The control where the renderer is added.
 };
 
 } // namespace Internal
 };
 
 } // namespace Internal
index 17d2246..cc68e0f 100644 (file)
@@ -69,8 +69,7 @@ public:
     IMAGE_SHADER_ATLAS_CUSTOM_WRAP,
     NINE_PATCH_SHADER,
     SVG_SHADER,
     IMAGE_SHADER_ATLAS_CUSTOM_WRAP,
     NINE_PATCH_SHADER,
     SVG_SHADER,
-    TEXT_SHADER_RGBA,
-    TEXT_SHADER_L8,
+    TEXT_SHADER,
     WIREFRAME_SHADER,
     SHADER_TYPE_MAX = WIREFRAME_SHADER
   };
     WIREFRAME_SHADER,
     SHADER_TYPE_MAX = WIREFRAME_SHADER
   };
index df0abce..5674716 100644 (file)
@@ -90,7 +90,6 @@ public:
     enum
     {
       /**
     enum
     {
       /**
-       * DEPRECATED_1_2.53 No longer be supported and will be ignored.
        * @brief The type of rendering e.g. bitmap-based.
        * @details name "renderingBackend", type INT, default RENDERING_SHARED_ATLAS.
        * @SINCE_1_0.0
        * @brief The type of rendering e.g. bitmap-based.
        * @details name "renderingBackend", type INT, default RENDERING_SHARED_ATLAS.
        * @SINCE_1_0.0