Added Drop Shadow properties and initial effect with Text Atlas Renderer 37/37437/5
authorRichard Underhill <r.underhill@partner.samsung.com>
Fri, 27 Mar 2015 10:42:04 +0000 (10:42 +0000)
committerRichard Underhill <r.underhill@partner.samsung.com>
Fri, 27 Mar 2015 14:41:41 +0000 (14:41 +0000)
Change-Id: Ic68310f1aca1a9f2700dd70ec4a0bf129d5a0f20
Signed-off-by: Richard Underhill <r.underhill@partner.samsung.com>
13 files changed:
dali-toolkit/internal/controls/text-controls/text-label-impl.cpp
dali-toolkit/internal/file.list
dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp
dali-toolkit/internal/text/rendering/shaders/text-basic-shadow-shader.cpp [new file with mode: 0644]
dali-toolkit/internal/text/rendering/shaders/text-basic-shadow-shader.h [new file with mode: 0644]
dali-toolkit/internal/text/text-controller.cpp
dali-toolkit/internal/text/text-controller.h
dali-toolkit/internal/text/text-view-interface.h
dali-toolkit/internal/text/text-view.cpp
dali-toolkit/internal/text/text-view.h
dali-toolkit/internal/text/visual-model-impl.cpp
dali-toolkit/internal/text/visual-model-impl.h
dali-toolkit/public-api/controls/text-controls/text-label.h

index 1da86f5..69bb5dc 100644 (file)
@@ -83,6 +83,8 @@ DALI_PROPERTY_REGISTRATION( TextLabel, "point-size",           FLOAT,   POINT_SI
 DALI_PROPERTY_REGISTRATION( TextLabel, "multi-line",           BOOLEAN, MULTI_LINE           )
 DALI_PROPERTY_REGISTRATION( TextLabel, "horizontal-alignment", STRING,  HORIZONTAL_ALIGNMENT )
 DALI_PROPERTY_REGISTRATION( TextLabel, "vertical-alignment",   STRING,  VERTICAL_ALIGNMENT   )
+DALI_PROPERTY_REGISTRATION( TextLabel, "shadow-offset",     VECTOR2, SHADOW_OFFSET     )
+DALI_PROPERTY_REGISTRATION( TextLabel, "shadow-color",      VECTOR4, SHADOW_COLOR      )
 
 DALI_TYPE_REGISTRATION_END()
 
@@ -218,6 +220,32 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
         }
         break;
       }
+     case Toolkit::TextLabel::Property::SHADOW_OFFSET:
+      {
+        if( impl.mController )
+        {
+          Vector2 shadowOffset = value.Get< Vector2 >();
+          if ( impl.mController->GetShadowOffset() != shadowOffset )
+          {
+            impl.mController->SetShadowOffset( shadowOffset );
+            impl.RequestTextRelayout();
+          }
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::SHADOW_COLOR:
+      {
+        if( impl.mController )
+        {
+          Vector4 shadowColor = value.Get< Vector4 >();
+          if ( impl.mController->GetShadowColor() != shadowColor )
+          {
+            impl.mController->SetShadowColor( shadowColor );
+            impl.RequestTextRelayout();
+          }
+        }
+        break;
+      }
     }
   }
 }
@@ -276,6 +304,22 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde
         }
         break;
       }
+     case Toolkit::TextLabel::Property::SHADOW_OFFSET:
+      {
+        if ( impl.mController )
+        {
+          value = impl.mController->GetShadowOffset();
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::SHADOW_COLOR:
+      {
+        if ( impl.mController )
+        {
+          value = impl.mController->GetShadowColor();
+        }
+        break;
+      }
     }
   }
 
index 5c38d49..d8b57e0 100644 (file)
@@ -99,6 +99,7 @@ toolkit_src_files = \
    $(toolkit_src_dir)/text/rendering/atlas/atlas-glyph-manager-impl.cpp \
    $(toolkit_src_dir)/text/rendering/basic/text-basic-renderer.cpp \
    $(toolkit_src_dir)/text/rendering/shaders/text-basic-shader.cpp \
+   $(toolkit_src_dir)/text/rendering/shaders/text-basic-shadow-shader.cpp \
    $(toolkit_src_dir)/text/rendering/shaders/text-bgra-shader.cpp \
    $(toolkit_src_dir)/text/rendering/text-backend-impl.cpp \
    $(toolkit_src_dir)/transition-effects/cube-transition-effect-impl.cpp \
index 41dfac9..3d8efde 100644 (file)
@@ -27,7 +27,7 @@
 #include <dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.h>
 #include <dali-toolkit/internal/text/rendering/shaders/text-basic-shader.h>
 #include <dali-toolkit/internal/text/rendering/shaders/text-bgra-shader.h>
-
+#include <dali-toolkit/internal/text/rendering/shaders/text-basic-shadow-shader.h>
 #if defined(DEBUG_ENABLED)
 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_ATLAS_RENDERER");
 #endif
@@ -43,13 +43,20 @@ namespace
   const Vector2 PADDING( 4.0f, 4.0f ); // Allow for variation in font glyphs
 }
 
-struct AtlasRenderer::Impl
+struct AtlasRenderer::Impl : public ConnectionTracker
 {
 
+  enum Style
+  {
+    STYLE_NORMAL,
+    STYLE_DROP_SHADOW
+  };
+
   struct MeshRecord
   {
     uint32_t mAtlasId;
     MeshData mMeshData;
+    FrameBufferImage mBuffer;
   };
 
   struct AtlasRecord
@@ -65,22 +72,31 @@ struct AtlasRenderer::Impl
   };
 
   Impl()
-  : mSlotDelegate( this )
   {
     mGlyphManager = AtlasGlyphManager::Get();
     mFontClient = TextAbstraction::FontClient::Get();
     mGlyphManager.SetNewAtlasSize( DEFAULT_ATLAS_SIZE, DEFAULT_BLOCK_SIZE );
     mBasicShader = BasicShader::New();
-    mBGRAShader = BgraShader::New();
+    mBgraShader = BgraShader::New();
+    mBasicShadowShader = BasicShadowShader::New();
   }
 
-  void AddGlyphs( const std::vector<Vector2>& positions, const Vector<GlyphInfo>& glyphs )
+  void AddGlyphs( const std::vector<Vector2>& positions,
+                  const Vector<GlyphInfo>& glyphs,
+                  const Vector2& shadowOffset,
+                  const Vector4& shadowColor )
   {
     AtlasManager::AtlasSlot slot;
     std::vector< MeshRecord > meshContainer;
     FontId lastFontId = 0;
+    Style style = STYLE_NORMAL;
 
-    if (mImageIds.Size() )
+    if ( shadowOffset.x > 0.0f || shadowOffset.y > 0.0f )
+    {
+      style = STYLE_DROP_SHADOW;
+    }
+
+    if ( mImageIds.Size() )
     {
       // Unreference any currently used glyphs
       RemoveText();
@@ -144,19 +160,23 @@ struct AtlasRenderer::Impl
     {
       for ( uint32_t i = 0; i < meshContainer.size(); ++i )
       {
-        Mesh mesh = Mesh::New( meshContainer[ i ].mMeshData );
-        MeshActor actor = MeshActor::New( mesh );
+        MeshActor actor = MeshActor::New( Mesh::New( meshContainer[ i ].mMeshData ) );
         actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
-        actor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );;
+        actor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
 
         // Check to see what pixel format the shader should be
         if ( mGlyphManager.GetPixelFormat( meshContainer[ i ].mAtlasId ) == Pixel::L8 )
         {
+          // Create an effect if necessary
+          if ( style == STYLE_DROP_SHADOW )
+          {
+            actor.Add( GenerateEffect( meshContainer[ i ], shadowOffset, shadowColor ) );
+          }
           actor.SetShaderEffect( mBasicShader );
         }
         else
         {
-          actor.SetShaderEffect( mBGRAShader );
+          actor.SetShaderEffect( mBgraShader );
         }
 
         if ( i )
@@ -168,7 +188,7 @@ struct AtlasRenderer::Impl
           mActor = actor;
         }
       }
-      mActor.OffStageSignal().Connect( mSlotDelegate, &AtlasRenderer::Impl::OffStageDisconnect );
+      mActor.OffStageSignal().Connect( this, &AtlasRenderer::Impl::OffStageDisconnect );
     }
 #if defined(DEBUG_ENABLED)
     Toolkit::AtlasGlyphManager::Metrics metrics = mGlyphManager.GetMetrics();
@@ -267,13 +287,158 @@ struct AtlasRenderer::Impl
     }
   }
 
+  MeshActor GenerateEffect( MeshRecord& meshRecord,
+                            const Vector2& shadowOffset,
+                            const Vector4& shadowColor )
+  {
+    // Scan vertex buffer to determine width and height of effect buffer needed
+    MeshData::VertexContainer verts = meshRecord.mMeshData.GetVertices();
+    const float zero = 0.0f;
+    const float one = 1.0f;
+    float tlx = verts[ 0 ].x;
+    float tly = verts[ 0 ].y;
+    float brx = zero;
+    float bry = zero;
+
+    for ( uint32_t i = 0; i < verts.size(); ++i )
+    {
+      if ( verts[ i ].x < tlx )
+      {
+        tlx = verts[ i ].x;
+      }
+      if ( verts[ i ].y < tly )
+      {
+        tly = verts[ i ].y;
+      }
+      if ( verts[ i ].x > brx )
+      {
+        brx = verts[ i ].x;
+      }
+      if ( verts[ i ].y > bry )
+      {
+        bry = verts[ i ].y;
+      }
+    }
+
+    float width = brx - tlx;
+    float height = bry - tly;
+    float divWidth = 2.0f / width;
+    float divHeight = 2.0f / height;
+
+    // Create a buffer to render to
+    // TODO bloom style filter from this buffer
+    meshRecord.mBuffer = FrameBufferImage::New( width, height );
+
+    // Create a mesh actor to contain the post-effect render
+    MeshData::VertexContainer vertices;
+    MeshData::FaceIndices face;
+
+    vertices.push_back( MeshData::Vertex( Vector3( tlx + shadowOffset.x, tly + shadowOffset.y, zero ),
+                                          Vector2( zero, zero ),
+                                          Vector3( zero, zero, zero ) ) );
+
+    vertices.push_back( MeshData::Vertex( Vector3( brx + shadowOffset.x, tly + shadowOffset.y, zero ),
+                                          Vector2( one, zero ),
+                                          Vector3( zero, zero, zero ) ) );
+
+    vertices.push_back( MeshData::Vertex( Vector3( tlx + shadowOffset.x, bry + shadowOffset.y, zero ),
+                                          Vector2( zero, one ),
+                                          Vector3( zero, zero, zero ) ) );
+
+    vertices.push_back( MeshData::Vertex( Vector3( brx + shadowOffset.x, bry + shadowOffset.y, zero ),
+                                          Vector2( one, one ),
+                                          Vector3( zero, zero, zero ) ) );
+
+    face.push_back( 0 ); face.push_back( 2u ); face.push_back( 1u );
+    face.push_back( 1u ); face.push_back( 2u ); face.push_back( 3u );
+
+    MeshData meshData;
+    Material newMaterial = Material::New("effect buffer");
+    newMaterial.SetDiffuseTexture( meshRecord.mBuffer );
+    meshData.SetMaterial( newMaterial );
+    meshData.SetVertices( vertices );
+    meshData.SetFaceIndices( face );
+    meshData.SetHasNormals( true );
+    meshData.SetHasColor( false );
+    meshData.SetHasTextureCoords( true );
+    MeshActor actor = MeshActor::New( Mesh::New( meshData ) );
+    actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
+    actor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
+    actor.SetShaderEffect( mBgraShader );
+    actor.SetFilterMode( FilterMode::LINEAR, FilterMode::LINEAR );
+    actor.SetSortModifier( one ); // force behind main text
+
+    // Create a sub actor to render once with normalized vertex positions
+    MeshData newMeshData;
+    MeshData::VertexContainer newVerts;
+    MeshData::FaceIndices newFaces;
+    MeshData::FaceIndices faces = meshRecord.mMeshData.GetFaces();
+    for ( uint32_t i = 0; i < verts.size(); ++i )
+    {
+      MeshData::Vertex vertex = verts[ i ];
+      vertex.x = ( ( vertex.x - tlx ) * divWidth ) - one;
+      vertex.y = ( ( vertex.y - tly ) * divHeight ) - one;
+      newVerts.push_back( vertex );
+    }
+
+    // Reverse triangle winding order
+    uint32_t faceCount = faces.size() / 3;
+    for ( uint32_t i = 0; i < faceCount; ++i )
+    {
+      uint32_t index = i * 3;
+      newFaces.push_back( faces[ index + 2 ] );
+      newFaces.push_back( faces[ index + 1 ] );
+      newFaces.push_back( faces[ index ] );
+    }
+
+    newMeshData.SetMaterial( meshRecord.mMeshData.GetMaterial() );
+    newMeshData.SetVertices( newVerts );
+    newMeshData.SetFaceIndices( newFaces );
+    newMeshData.SetHasNormals( true );
+    newMeshData.SetHasColor( false );
+    newMeshData.SetHasTextureCoords( true );
+
+    MeshActor subActor = MeshActor::New( Mesh::New( newMeshData ) );
+    subActor.SetParentOrigin( ParentOrigin::TOP_LEFT );
+    subActor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
+    subActor.SetColor( shadowColor );
+    subActor.SetShaderEffect( mBasicShadowShader );
+    subActor.SetFilterMode( FilterMode::NEAREST, FilterMode::NEAREST );
+
+    // Create a render task to render the effect
+    RenderTask task = Stage::GetCurrent().GetRenderTaskList().CreateTask();
+    task.SetTargetFrameBuffer( meshRecord.mBuffer );
+    task.SetSourceActor( subActor );
+    task.SetClearEnabled( true );
+    task.SetClearColor( Vector4::ZERO );
+    task.SetExclusive( true );
+    task.SetRefreshRate( RenderTask::REFRESH_ONCE );
+    task.FinishedSignal().Connect( this, &AtlasRenderer::Impl::RenderComplete );
+    actor.Add( subActor );
+    return actor;
+  }
+
+  void RenderComplete( RenderTask& renderTask )
+  {
+    // Get the actor used for render to buffer and remove it from the parent
+    Actor renderActor = renderTask.GetSourceActor();
+    if ( renderActor )
+    {
+      Actor parent = renderActor.GetParent();
+      if ( parent )
+      {
+        parent.Remove( renderActor );
+      }
+    }
+  }
+
   RenderableActor mActor;                             ///< The actor parent which renders the text
   AtlasGlyphManager mGlyphManager;                    ///< Glyph Manager to handle upload and caching
   Vector< uint32_t > mImageIds;                       ///< A list of imageIDs used by the renderer
   TextAbstraction::FontClient mFontClient;            ///> The font client used to supply glyph information
-  SlotDelegate< AtlasRenderer::Impl > mSlotDelegate;  ///> Signal generated to unreference glyphs when renderable actor is removed
-  ShaderEffect mBasicShader;                          ///> Shader to render L8 glyphs
-  ShaderEffect mBGRAShader;                           ///> Shader to render BGRA glyphs
+  ShaderEffect mBasicShader;                          ///> Shader used to render L8 glyphs
+  ShaderEffect mBgraShader;                           ///> Shader used to render BGRA glyphs
+  ShaderEffect mBasicShadowShader;                    ///> Shader used to render drop shadow into buffer
   std::vector< MaxBlockSize > mBlockSizes;            ///> Maximum size needed to contain a glyph in a block within a new atlas
 };
 
@@ -299,7 +464,10 @@ RenderableActor AtlasRenderer::Render( Text::ViewInterface& view )
     std::vector<Vector2> positions;
     positions.resize( numberOfGlyphs );
     view.GetGlyphPositions( &positions[0], 0, numberOfGlyphs );
-    mImpl->AddGlyphs( positions, glyphs );
+    mImpl->AddGlyphs( positions,
+                      glyphs,
+                      view.GetShadowOffset(),
+                      view.GetShadowColor() );
   }
   return mImpl->mActor;
 }
diff --git a/dali-toolkit/internal/text/rendering/shaders/text-basic-shadow-shader.cpp b/dali-toolkit/internal/text/rendering/shaders/text-basic-shadow-shader.cpp
new file mode 100644 (file)
index 0000000..f7789f1
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/internal/text/rendering/text-renderer.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+namespace BasicShadowShader
+{
+
+Dali::ShaderEffect New()
+{
+  std::string vertexShader = DALI_COMPOSE_SHADER(
+      void main()\n
+      {\n
+        gl_Position = vec4( aPosition.xy, 0.0, 1.0 );\n
+        vTexCoord = aTexCoord.xy;\n
+      }\n
+  );
+
+  std::string fragmentShader = DALI_COMPOSE_SHADER(
+      void main()\n
+      {\n
+        mediump vec4 color = texture2D( sTexture, vTexCoord );
+        gl_FragColor = vec4(uColor.rgb, uColor.a*color.r);
+      }\n
+  );
+
+  Dali::ShaderEffect shaderEffect = Dali::ShaderEffect::New( vertexShader, fragmentShader,
+                                                             Dali::GeometryType( Dali::GEOMETRY_TYPE_TEXTURED_MESH ),
+                                                             Dali::ShaderEffect::GeometryHints( Dali::ShaderEffect::HINT_NONE ) );
+  return shaderEffect;
+}
+
+} // namespace BasicShadowShader
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/text/rendering/shaders/text-basic-shadow-shader.h b/dali-toolkit/internal/text/rendering/shaders/text-basic-shadow-shader.h
new file mode 100644 (file)
index 0000000..93bd0a3
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef __DALI_TOOLKIT_TEXT_BASIC_SHADOW_SHADER_H__
+#define __DALI_TOOLKIT_TEXT_BASIC_SHADOW_SHADER_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/shader-effects/shader-effect.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+/**
+ * @brief A basic shader for rendering glyphs in Pixel::L8 format.
+ */
+namespace BasicShadowShader
+{
+
+/**
+ * Create a basic text shadow shader.
+ * @return A handle to a newly allocated ShaderEffect
+ */
+Dali::ShaderEffect New();
+
+} // namespace BasicShadowShader
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_BASIC_SHADOW_SHADER_H__
index ae4bbac..219d8e5 100644 (file)
@@ -650,6 +650,10 @@ struct Controller::Impl
     mFontClient = TextAbstraction::FontClient::Get();
 
     mView.SetVisualModel( mVisualModel );
+
+    // Set the shadow properties to default
+    mVisualModel->SetShadowOffset( Vector2::ZERO );
+    mVisualModel->SetShadowColor( Vector4::ZERO );
   }
 
   ~Impl()
@@ -845,6 +849,26 @@ void Controller::GetDefaultFonts( Vector<FontRun>& fonts, Length numberOfCharact
   }
 }
 
+const Vector2& Controller::GetShadowOffset() const
+{
+  return mImpl->mVisualModel->GetShadowOffset();
+}
+
+const Vector4& Controller::GetShadowColor() const
+{
+  return mImpl->mVisualModel->GetShadowColor();
+}
+
+void Controller::SetShadowOffset( const Vector2& shadowOffset )
+{
+  mImpl->mVisualModel->SetShadowOffset( shadowOffset );
+}
+
+void Controller::SetShadowColor( const Vector4& shadowColor )
+{
+  mImpl->mVisualModel->SetShadowColor( shadowColor );
+}
+
 void Controller::EnableTextInput( DecoratorPtr decorator )
 {
   if( !mImpl->mTextInput )
index 2935299..ddb1051 100644 (file)
@@ -173,6 +173,34 @@ public:
   void GetDefaultFonts( Dali::Vector<FontRun>& fonts, Length numberOfCharacters );
 
   /**
+   * @brief Set the shadow offset.
+   *
+   * @param[in] shadowOffset The shadow offset, 0,0 indicates no shadow.
+   */
+   void SetShadowOffset( const Vector2& shadowOffset );
+
+  /**
+   * @brief Retrieve the shadow offset.
+   *
+   * @return The shadow offset.
+   */
+   const Vector2& GetShadowOffset() const;
+
+  /**
+   * @brief Set the shadow color.
+   *
+   * @param[in] shadowColor The shadow color.
+   */
+   void SetShadowColor( const Vector4& shadowColor );
+
+  /**
+   * @brief Retrieve the shadow color.
+   *
+   * @return The shadow color.
+   */
+   const Vector4& GetShadowColor() const;
+
+  /**
    * @brief Called to enable text input.
    *
    * @note Only selectable or editable controls should calls this.
index d005a4a..4220b66 100644 (file)
@@ -18,6 +18,9 @@
  *
  */
 
+// EXTERNAL INCLUDES
+#include <dali/public-api/math/vector4.h>
+
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/text-definitions.h>
 
@@ -84,6 +87,20 @@ public:
   virtual void GetGlyphPositions( Vector2* glyphPositions,
                                   GlyphIndex glyphIndex,
                                   Length numberOfGlyphs ) const = 0;
+
+  /**
+   * @brief Retrieves the shadow offset, 0,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;
 };
 
 } // namespace Text
index d12c697..bfe3f70 100644 (file)
@@ -51,6 +51,26 @@ void View::SetVisualModel( VisualModelPtr visualModel )
   mImpl->mVisualModel = visualModel;
 }
 
+const Vector2& View::GetShadowOffset() const
+{
+  if ( mImpl->mVisualModel )
+  {
+    VisualModel& model = *mImpl->mVisualModel;
+    return model.GetShadowOffset();
+  }
+  return Vector2::ZERO;
+}
+
+const Vector4& View::GetShadowColor() const
+{
+  if ( mImpl->mVisualModel )
+  {
+    VisualModel& model = *mImpl->mVisualModel;
+    return model.GetShadowColor();
+  }
+  return Vector4::ZERO;
+}
+
 Length View::GetNumberOfGlyphs() const
 {
   if( mImpl->mVisualModel )
index 56ce0be..ba4d3bd 100644 (file)
@@ -76,6 +76,16 @@ public:
                                   GlyphIndex glyphIndex,
                                   Length numberOfGlyphs ) const;
 
+  /**
+   * @copydoc Dali::Toolkit::Text::ViewInterface::GetShadowOffset()
+   */
+  virtual const Vector2& GetShadowOffset() const;
+
+  /**
+   * @copydoc Dali::Toolkit::Text::ViewInterface::GetShadowColor()
+   */
+  virtual const Vector4& GetShadowColor() const;
+
 private:
 
   // Undefined
index 74291b4..0c056ad 100644 (file)
@@ -370,6 +370,27 @@ const Vector2& VisualModel::GetActualSize() const
   return mActualSize;
 }
 
+void VisualModel::SetShadowOffset( const Vector2& shadowOffset )
+{
+  mShadowOffset = shadowOffset;
+}
+
+void VisualModel::SetShadowColor( const Vector4& shadowColor )
+{
+  mShadowColor = shadowColor;
+}
+
+const Vector2& VisualModel::GetShadowOffset() const
+{
+  return mShadowOffset;
+}
+
+const Vector4& VisualModel::GetShadowColor() const
+{
+  return mShadowColor;
+}
+
+
 VisualModel::~VisualModel()
 {
 }
index e5af4c3..9deaea7 100644 (file)
@@ -21,6 +21,7 @@
 // EXTERNAL INCLUDES
 #include <dali/public-api/common/dali-vector.h>
 #include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/math/vector4.h>
 #include <dali/public-api/object/ref-object.h>
 
 // INTERNAL INCLUDES
@@ -383,6 +384,34 @@ public:
    */
   const Vector2& GetActualSize() const;
 
+  /**
+   * @brief Sets the text's shadow offset.
+   *
+   * @param[in] shadowOffset The shadow offset, 0,0 indicates no shadow.
+   */
+  void SetShadowOffset( const Vector2& shadowOffset );
+
+  /**
+   * @brief Retrieves the text's shadow offset.
+   *
+   * @return The text's shadow offset, 0,0 indicates no shadow.
+   */
+  const Vector2& GetShadowOffset() const;
+
+  /**
+   * @brief Sets the text's shadow color.
+   *
+   * @param[in] shadowColor The shadow color.
+   */
+  void SetShadowColor( const Vector4& shadowColor );
+
+  /**
+   * @brief Retrieves the text's shadow color.
+   *
+   * @return The text's shadow color.
+   */
+  const Vector4& GetShadowColor() const;
+
 protected:
 
   /**
@@ -413,6 +442,9 @@ public:
   Vector<Vector2>        mGlyphPositions;     ///< For each glyph, the position.
   Vector<LineRun>        mLines;              ///< The laid out lines.
 
+  Vector2                mShadowOffset;       ///< Offset for drop shadow, 0.0 indicates no shadow
+  Vector4                mShadowColor;        ///< Color of drop shadow
+
 private:
 
   Size                   mNaturalSize;        ///< Size of the text with no line wrapping.
index 37f2771..ba755da 100644 (file)
@@ -64,7 +64,9 @@ public:
       POINT_SIZE,                               ///< name "point-size",           The size of font in points,                   type FLOAT
       MULTI_LINE,                               ///< name "multi-line",           The single-line or multi-line layout option,  type BOOLEAN
       HORIZONTAL_ALIGNMENT,                     ///< name "horizontal-alignment", The line horizontal alignment,                type STRING,  values "BEGIN", "CENTER", "END"
-      VERTICAL_ALIGNMENT                        ///< name "vertical-alignment",   The line vertical alignment,                  type STRING,  values   "TOP",   "CENTER",   "BOTTOM"
+      VERTICAL_ALIGNMENT,                        ///< name "vertical-alignment",   The line vertical alignment,                  type STRING,  values   "TOP",   "CENTER",   "BOTTOM"
+      SHADOW_OFFSET,                            ///< name "shadow-offset",        The drop shadow offset 0 indicates no shadow, type VECTOR2
+      SHADOW_COLOR,                             ///< name "shadow-color",         The color of a drop shadow                  , type VECTOR4
     };
   };