Merge "Add Placeholder Ellipsis in TextField" into devel/master
authorHyunJu Shin <hyunjushin@samsung.com>
Mon, 25 Sep 2017 06:59:26 +0000 (06:59 +0000)
committerGerrit Code Review <gerrit@review.ap-northeast-2.compute.internal>
Mon, 25 Sep 2017 06:59:26 +0000 (06:59 +0000)
21 files changed:
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-text-abstraction.cpp [changed mode: 0644->0755]
automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp
dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp
dali-toolkit/internal/text/rendering/text-typesetter.cpp [changed mode: 0644->0755]
dali-toolkit/internal/text/rendering/view-model.cpp [changed mode: 0644->0755]
dali-toolkit/internal/text/rendering/view-model.h [changed mode: 0644->0755]
dali-toolkit/internal/text/text-controller.cpp [changed mode: 0644->0755]
dali-toolkit/internal/text/text-controller.h [changed mode: 0644->0755]
dali-toolkit/internal/text/text-effects-style.cpp [changed mode: 0644->0755]
dali-toolkit/internal/text/text-effects-style.h [changed mode: 0644->0755]
dali-toolkit/internal/text/text-font-style.cpp
dali-toolkit/internal/text/text-model-interface.h [changed mode: 0644->0755]
dali-toolkit/internal/text/text-model.cpp [changed mode: 0644->0755]
dali-toolkit/internal/text/text-model.h [changed mode: 0644->0755]
dali-toolkit/internal/text/visual-model-impl.cpp [changed mode: 0644->0755]
dali-toolkit/internal/text/visual-model-impl.h [changed mode: 0644->0755]
dali-toolkit/internal/visuals/text/text-visual.cpp [changed mode: 0644->0755]
dali-toolkit/public-api/dali-toolkit-version.cpp
packaging/dali-toolkit.spec

old mode 100644 (file)
new mode 100755 (executable)
index df25aaa..5cc9401
@@ -152,8 +152,8 @@ public:
   void GetFontMetrics( FontId fontId, FontMetrics& metrics ){}
   GlyphIndex GetGlyphIndex( FontId fontId, Character charcode ){return 0;}
   bool GetGlyphMetrics( GlyphInfo* array, uint32_t size, bool horizontal ){return true;}
-  void CreateBitmap( FontId fontId, GlyphIndex glyphIndex, Dali::TextAbstraction::FontClient::GlyphBufferData& data ){}
-  PixelData CreateBitmap( FontId fontId, GlyphIndex glyphIndex ){return PixelData();}
+  void CreateBitmap( FontId fontId, GlyphIndex glyphIndex, Dali::TextAbstraction::FontClient::GlyphBufferData& data, int outlineWidth ){}
+  PixelData CreateBitmap( FontId fontId, GlyphIndex glyphIndex, int outlineWidth ){return PixelData();}
   void CreateVectorBlob( FontId fontId, GlyphIndex glyphIndex, VectorBlob*& blob,
                          unsigned int& blobLength, unsigned int& nominalWidth, unsigned int& nominalHeight )
   {
@@ -472,14 +472,14 @@ bool FontClient::GetGlyphMetrics( GlyphInfo* array, uint32_t size, GlyphType typ
   return GetImplementation(*this).GetGlyphMetrics( array, size, horizontal );
 }
 
-void FontClient::CreateBitmap( FontId fontId, GlyphIndex glyphIndex, Dali::TextAbstraction::FontClient::GlyphBufferData& data )
+void FontClient::CreateBitmap( FontId fontId, GlyphIndex glyphIndex, Dali::TextAbstraction::FontClient::GlyphBufferData& data, int outlineWidth )
 {
-  GetImplementation(*this).CreateBitmap( fontId, glyphIndex, data );
+  GetImplementation(*this).CreateBitmap( fontId, glyphIndex, data, outlineWidth );
 }
 
-PixelData FontClient::CreateBitmap( FontId fontId, GlyphIndex glyphIndex )
+PixelData FontClient::CreateBitmap( FontId fontId, GlyphIndex glyphIndex, int outlineWidth )
 {
-  return GetImplementation(*this).CreateBitmap( fontId, glyphIndex );
+  return GetImplementation(*this).CreateBitmap( fontId, glyphIndex, outlineWidth );
 }
 
 void FontClient::CreateVectorBlob( FontId fontId,
index 3fd4bd6..59925df 100644 (file)
@@ -732,8 +732,19 @@ int UtcDaliTextEditorSetPropertyP(void)
   DALI_TEST_EQUALS( editor.GetProperty<std::string>( TextEditor::Property::INPUT_EMBOSS ), std::string("Emboss input properties"), TEST_LOCATION );
 
   // Check the outline property
-  editor.SetProperty( TextEditor::Property::OUTLINE, "Outline properties" );
-  DALI_TEST_EQUALS( editor.GetProperty<std::string>( TextEditor::Property::OUTLINE ), std::string("Outline properties"), TEST_LOCATION );
+  Property::Map outlineMapSet;
+  Property::Map outlineMapGet;
+
+  outlineMapSet["color"] = Color::RED;
+  outlineMapSet["width"] = 2.0f;
+
+  editor.SetProperty( TextEditor::Property::OUTLINE, outlineMapSet );
+
+  outlineMapSet["color"] = "red";
+  outlineMapSet["width"] = "2";
+  outlineMapGet = editor.GetProperty<Property::Map>( TextEditor::Property::OUTLINE );
+  DALI_TEST_EQUALS( outlineMapGet.Count(), outlineMapSet.Count(), TEST_LOCATION );
+  DALI_TEST_EQUALS( DaliTestCheckMaps( outlineMapGet, outlineMapSet ), true, TEST_LOCATION );
 
   // Check the input outline property
   editor.SetProperty( TextEditor::Property::INPUT_OUTLINE, "Outline input properties" );
index b4bd556..df0a150 100644 (file)
@@ -829,8 +829,19 @@ int UtcDaliTextFieldSetPropertyP(void)
   DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::INPUT_EMBOSS ), std::string("Emboss input properties"), TEST_LOCATION );
 
   // Check the outline property
-  field.SetProperty( TextField::Property::OUTLINE, "Outline properties" );
-  DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::OUTLINE ), std::string("Outline properties"), TEST_LOCATION );
+  Property::Map outlineMapSet;
+  Property::Map outlineMapGet;
+
+  outlineMapSet["color"] = Color::RED;
+  outlineMapSet["width"] = 2.0f;
+
+  field.SetProperty( TextField::Property::OUTLINE, outlineMapSet );
+
+  outlineMapSet["color"] = "red";
+  outlineMapSet["width"] = "2";
+  outlineMapGet = field.GetProperty<Property::Map>( TextField::Property::OUTLINE );
+  DALI_TEST_EQUALS( outlineMapGet.Count(), outlineMapSet.Count(), TEST_LOCATION );
+  DALI_TEST_EQUALS( DaliTestCheckMaps( outlineMapGet, outlineMapSet ), true, TEST_LOCATION );
 
   // Check the input outline property
   field.SetProperty( TextField::Property::INPUT_OUTLINE, "Outline input properties" );
index beba3a6..2f2e692 100644 (file)
@@ -434,8 +434,18 @@ int UtcDaliToolkitTextLabelSetPropertyP(void)
   DALI_TEST_EQUALS( label.GetProperty<std::string>( TextLabel::Property::EMBOSS ), std::string("Emboss properties"), TEST_LOCATION );
 
   // Check the outline property
-  label.SetProperty( TextLabel::Property::OUTLINE, "Outline properties" );
-  DALI_TEST_EQUALS( label.GetProperty<std::string>( TextLabel::Property::OUTLINE ), std::string("Outline properties"), TEST_LOCATION );
+  Property::Map outlineMapSet;
+  Property::Map outlineMapGet;
+
+  outlineMapSet["color"] = Color::RED;
+  outlineMapSet["width"] = 2.0f;
+  label.SetProperty( TextLabel::Property::OUTLINE, outlineMapSet );
+
+  outlineMapSet["color"] = "red";
+  outlineMapSet["width"] = "2";
+  outlineMapGet = label.GetProperty<Property::Map>( TextLabel::Property::OUTLINE );
+  DALI_TEST_EQUALS( outlineMapGet.Count(), outlineMapSet.Count(), TEST_LOCATION );
+  DALI_TEST_EQUALS( DaliTestCheckMaps( outlineMapGet, outlineMapSet ), true, TEST_LOCATION );
 
   // Check the pixel size of font
   label.SetProperty( DevelTextLabel::Property::PIXEL_SIZE, 20.f );
@@ -990,3 +1000,71 @@ int UtcDaliToolkitTextLabelColorComponents(void)
 
   END_TEST;
 }
+
+int UtcDaliToolkitTextlabelTextStyle01(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextlabelTextStyle Setting Outline after Shadow");
+
+  TextLabel label = TextLabel::New();
+  label.SetSize( 300.0f, 300.f );
+  label.SetProperty( TextLabel::Property::TEXT, "Hello world Hello world" );
+  label.SetProperty( TextLabel::Property::POINT_SIZE, 12 );
+  Stage::GetCurrent().Add( label );
+
+  Property::Map outlineMapSet;
+  Property::Map outlineMapGet;
+
+  outlineMapSet["color"] = Color::BLUE;
+  outlineMapSet["width"] = 2.0f;
+  label.SetProperty( TextLabel::Property::OUTLINE, outlineMapSet );
+
+  application.SendNotification();
+  application.Render();
+
+  Property::Map shadowMapSet;
+  shadowMapSet.Insert( "color", "green" );
+  shadowMapSet.Insert( "offset", "2 2" );
+  label.SetProperty( TextLabel::Property::SHADOW, shadowMapSet );
+
+  outlineMapSet["color"] = Color::RED;
+  outlineMapSet["width"] = 0.0f;
+  label.SetProperty( TextLabel::Property::OUTLINE, outlineMapSet );
+
+  application.SendNotification();
+  application.Render();
+
+  outlineMapGet = label.GetProperty<Property::Map>( TextLabel::Property::OUTLINE );
+
+  Property::Value* colorValue = outlineMapGet.Find("color");
+
+  bool colorMatched( false );
+
+  if ( colorValue )
+  {
+     Property::Type valueType = colorValue->GetType();
+
+     if ( Property::STRING == valueType )
+     {
+       std::string stringValue;
+       colorValue->Get( stringValue );
+       if (  stringValue == "red" )
+       {
+         colorMatched = true;
+       }
+     }
+     else if ( Property::VECTOR4 == valueType )
+     {
+       Vector4 colorVector4;
+       colorValue->Get( colorVector4 );
+       if (  colorVector4 == Color::RED )
+       {
+         colorMatched = true;
+       }
+     }
+  }
+
+  DALI_TEST_EQUALS( colorMatched, true, TEST_LOCATION );
+
+  END_TEST;
+}
index 13eeae6..62865d6 100644 (file)
@@ -94,6 +94,7 @@ const float HALF( 0.5f );
 const float ONE( 1.0f );
 const uint32_t DEFAULT_ATLAS_WIDTH = 512u;
 const uint32_t DEFAULT_ATLAS_HEIGHT = 512u;
+const int NO_OUTLINE( 0 );
 }
 
 struct AtlasRenderer::Impl
@@ -354,7 +355,8 @@ struct AtlasRenderer::Impl
 
           mFontClient.CreateBitmap( glyph.fontId,
                                     glyph.index,
-                                    glyphBufferData );
+                                    glyphBufferData,
+                                    NO_OUTLINE );
 
           // Create the pixel data.
           bitmap = PixelData::New( glyphBufferData.buffer,
old mode 100644 (file)
new mode 100755 (executable)
index 66bb797..b524710
@@ -102,7 +102,7 @@ void TypesetGlyph( GlyphData& data,
       if( ( 0 > yOffsetIndex ) || ( yOffsetIndex > heightMinusOne ) )
       {
         // Do not write out of bounds.
-        break;
+        continue;
       }
 
       const int verticalOffset = yOffsetIndex * data.width;
@@ -114,7 +114,7 @@ void TypesetGlyph( GlyphData& data,
         if( ( 0 > xOffsetIndex ) || ( xOffsetIndex > widthMinusOne ) )
         {
           // Don't write out of bounds.
-          break;
+          continue;
         }
 
         uint32_t* bitmapBuffer = reinterpret_cast< uint32_t* >( data.bitmapBuffer.GetBuffer() );
@@ -138,7 +138,7 @@ void TypesetGlyph( GlyphData& data,
           }
 
           // Update the alpha channel.
-          if( Typesetter::STYLE_MASK == style )
+          if( Typesetter::STYLE_MASK == style || Typesetter::STYLE_OUTLINE == style ) // Outline not shown for color glyph
           {
             // Create an alpha mask for color glyph.
             *( packedColorGlyphBuffer + 3u ) = 0u;
@@ -191,7 +191,7 @@ void TypesetGlyph( GlyphData& data,
       if( ( 0 > yOffsetIndex ) || ( yOffsetIndex > heightMinusOne ) )
       {
         // Do not write out of bounds.
-        break;
+        continue;
       }
 
       const int verticalOffset = yOffsetIndex * data.width;
@@ -203,7 +203,7 @@ void TypesetGlyph( GlyphData& data,
         if( ( 0 > xOffsetIndex ) || ( xOffsetIndex > widthMinusOne ) )
         {
           // Don't write out of bounds.
-          break;
+          continue;
         }
 
         uint8_t* bitmapBuffer = reinterpret_cast< uint8_t* >( data.bitmapBuffer.GetBuffer() );
@@ -217,7 +217,6 @@ void TypesetGlyph( GlyphData& data,
           // 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
@@ -327,6 +326,18 @@ PixelData Typesetter::Render( const Vector2& size, RenderBehaviour behaviour, bo
 
   if ( ( RENDER_NO_STYLES != behaviour ) && ( RENDER_MASK != behaviour ) )
   {
+
+    // Generate the outline if enabled
+    const float outlineWidth = mModel->GetOutlineWidth();
+    if ( outlineWidth > Math::MACHINE_EPSILON_1 )
+    {
+      // Create the image buffer for outline
+      Devel::PixelBuffer outlineImageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_OUTLINE, ignoreHorizontalAlignment, pixelFormat, penY, 0u, numberOfGlyphs -1 );
+
+      // Combine the two buffers
+      imageBuffer = CombineImageBuffer( imageBuffer, outlineImageBuffer, bufferWidth, bufferHeight );
+    }
+
     // @todo. Support shadow and underline for partial text later on.
 
     // Generate the shadow if enabled
@@ -379,6 +390,7 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth
   glyphData.width = bufferWidth;
   glyphData.height = bufferHeight;
   glyphData.bitmapBuffer = Devel::PixelBuffer::New( bufferWidth, bufferHeight, pixelFormat );
+  glyphData.horizontalOffset = 0;
 
   if ( Pixel::RGBA8888 == pixelFormat )
   {
@@ -405,14 +417,27 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth
     // Increases the vertical offset with the line's ascender.
     glyphData.verticalOffset += static_cast<int>( line.ascender );
 
-    if ( style == Typesetter::STYLE_SHADOW )
+    // Retrieves the glyph's outline width
+    float outlineWidth = mModel->GetOutlineWidth();
+
+    if( style == Typesetter::STYLE_OUTLINE )
+    {
+      glyphData.horizontalOffset -= outlineWidth;
+      if( lineIndex == 0u )
+      {
+        // Only need to add the vertical outline offset for the first line
+        glyphData.verticalOffset -= outlineWidth;
+      }
+    }
+    else if ( style == Typesetter::STYLE_SHADOW )
     {
       const Vector2& shadowOffset = mModel->GetShadowOffset();
-      glyphData.horizontalOffset += shadowOffset.x;
+      glyphData.horizontalOffset += shadowOffset.x - outlineWidth; // if outline enabled then shadow should offset from outline
+
       if ( lineIndex == 0u )
       {
-        // Only need to add the vertical shadow offset for once
-        glyphData.verticalOffset += shadowOffset.y;
+        // Only need to add the vertical shadow offset for first line
+        glyphData.verticalOffset += shadowOffset.y - outlineWidth;
       }
     }
 
@@ -532,6 +557,10 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth
       {
         color = &( mModel->GetShadowColor() );
       }
+      else if ( style == Typesetter::STYLE_OUTLINE )
+      {
+        color = &( mModel->GetOutlineColor() );
+      }
       else
       {
         color = ( useDefaultColor || ( 0u == colorIndex ) ) ? &defaultColor : colorsBuffer + ( colorIndex - 1u );
@@ -541,9 +570,17 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth
       glyphData.glyphBitmap.buffer = NULL;
       glyphData.glyphBitmap.width = glyphInfo->width;   // Desired width and height.
       glyphData.glyphBitmap.height = glyphInfo->height;
+
+      if( style != Typesetter::STYLE_OUTLINE && style != Typesetter::STYLE_SHADOW )
+      {
+        // Don't render outline for other styles
+        outlineWidth = 0.0f;
+      }
+
       fontClient.CreateBitmap( glyphInfo->fontId,
                                glyphInfo->index,
-                               glyphData.glyphBitmap );
+                               glyphData.glyphBitmap,
+                               outlineWidth );
 
       // Sets the glyph's bitmap into the bitmap of the whole text.
       if( NULL != glyphData.glyphBitmap.buffer )
old mode 100644 (file)
new mode 100755 (executable)
index 1dcda36..fe3c451
@@ -188,6 +188,16 @@ void ViewModel::GetUnderlineRuns( GlyphRun* underlineRuns, UnderlineRunIndex ind
   mModel->GetUnderlineRuns( underlineRuns, index, numberOfRuns );
 }
 
+const Vector4& ViewModel::GetOutlineColor() const
+{
+  return mModel->GetOutlineColor();
+}
+
+float ViewModel::GetOutlineWidth() const
+{
+  return mModel->GetOutlineWidth();
+}
+
 void ViewModel::ElideGlyphs()
 {
   mIsTextElided = false;
old mode 100644 (file)
new mode 100755 (executable)
index e15fa9c..827ecf0
@@ -172,6 +172,16 @@ public:
   virtual void GetUnderlineRuns( GlyphRun* underlineRuns, UnderlineRunIndex index, Length numberOfRuns ) const;
 
   /**
+   * @copydoc ModelInterface::GetOutlineColor()
+   */
+  virtual const Vector4& GetOutlineColor() const;
+
+  /**
+   * @copydoc ModelInterface::GetOutlineWidth()
+   */
+  virtual float GetOutlineWidth() const;
+
+ /**
    * @brief Does the text elide.
    *
    * It stores a copy of the visible glyphs and removes as many glyphs as needed
old mode 100644 (file)
new mode 100755 (executable)
index 4ca2d9a..4cc9d90
@@ -1148,6 +1148,30 @@ float Controller::GetUnderlineHeight() const
   return mImpl->mModel->mVisualModel->GetUnderlineHeight();
 }
 
+void Controller::SetOutlineColor( const Vector4& color )
+{
+  mImpl->mModel->mVisualModel->SetOutlineColor( color );
+
+  mImpl->RequestRelayout();
+}
+
+const Vector4& Controller::GetOutlineColor() const
+{
+  return mImpl->mModel->mVisualModel->GetOutlineColor();
+}
+
+void Controller::SetOutlineWidth( float width )
+{
+  mImpl->mModel->mVisualModel->SetOutlineWidth( width );
+
+  mImpl->RequestRelayout();
+}
+
+float Controller::GetOutlineWidth() const
+{
+  return mImpl->mModel->mVisualModel->GetOutlineWidth();
+}
+
 void Controller::SetDefaultEmbossProperties( const std::string& embossProperties )
 {
   if( NULL == mImpl->mEmbossDefaults )
old mode 100644 (file)
new mode 100755 (executable)
index 609fe7a..b02bb68
@@ -789,6 +789,34 @@ public: // Default style & Input style
   float GetUnderlineHeight() const;
 
   /**
+   * @brief Set the outline color.
+   *
+   * @param[in] color color of outline.
+   */
+  void SetOutlineColor( const Vector4& color );
+
+  /**
+   * @brief Retrieve the outline color.
+   *
+   * @return The outline color.
+   */
+  const Vector4& GetOutlineColor() const;
+
+  /**
+   * @brief Set the outline width
+   *
+   * @param[in] width The width in pixels of the outline, 0 indicates no outline
+   */
+  void SetOutlineWidth( float width );
+
+  /**
+   * @brief Retrieves the width of an outline
+   *
+   * @return The width of the outline.
+   */
+  float GetOutlineWidth() const;
+
+  /**
    * @brief Sets the emboss's properties string.
    *
    * @note The string is stored to be recovered.
old mode 100644 (file)
new mode 100755 (executable)
index 75fabd7..8b71d30
@@ -35,6 +35,7 @@ namespace
 {
 const std::string COLOR_KEY( "color" );
 const std::string OFFSET_KEY( "offset" );
+const std::string WIDTH_KEY( "width" );
 const std::string HEIGHT_KEY( "height" );
 const std::string ENABLE_KEY( "enable" );
 const std::string TRUE_TOKEN( "true" );
@@ -120,6 +121,36 @@ bool ParseUnderlineProperties( const Property::Map& underlinePropertiesMap,
   return 0u == numberOfItems;
 }
 
+bool ParseOutlineProperties( const Property::Map& underlinePropertiesMap,
+                               bool& colorDefined,
+                               Vector4& color,
+                               bool& widthDefined,
+                               float& width )
+{
+  const unsigned int numberOfItems = underlinePropertiesMap.Count();
+
+  // Parses and applies the style.
+  for( unsigned int index = 0u; index < numberOfItems; ++index )
+  {
+    const KeyValuePair& valueGet = underlinePropertiesMap.GetKeyValue( index );
+
+    if( COLOR_KEY == valueGet.first.stringKey )
+    {
+      /// Color key.
+      colorDefined = true;
+      color = valueGet.second.Get<Vector4>();
+    }
+    else if( WIDTH_KEY == valueGet.first.stringKey )
+    {
+      /// Width key.
+      widthDefined = true;
+      width = valueGet.second.Get<float>();
+    }
+  }
+
+  return 0u == numberOfItems;
+}
+
 bool SetUnderlineProperties( ControllerPtr controller, const Property::Value& value, EffectStyle::Type type )
 {
   bool update = false;
@@ -463,24 +494,63 @@ bool SetOutlineProperties( ControllerPtr controller, const Property::Value& valu
 
   if( controller )
   {
-    const std::string properties = value.Get< std::string >();
-
     switch( type )
     {
       case EffectStyle::DEFAULT:
       {
-        // Stores the default outline's properties string to be recovered by the GetOutlineProperties() function.
-        controller->SetDefaultOutlineProperties( properties );
+        const Property::Map& propertiesMap = value.Get<Property::Map>();
+
+        bool colorDefined = false;
+        Vector4 color;
+        bool widthDefined = false;
+        float width = 0.f;
+
+        bool empty = true;
+
+        if ( !propertiesMap.Empty() )
+        {
+           empty = ParseOutlineProperties( propertiesMap,
+                                           colorDefined,
+                                           color,
+                                           widthDefined,
+                                           width );
+        }
+
+        if( !empty )
+        {
+          // Sets the default outline values.
+          if( colorDefined && ( controller->GetOutlineColor() != color ) )
+          {
+            controller->SetOutlineColor( color );
+            update = true;
+          }
+
+          if( widthDefined && ( fabsf( controller->GetOutlineWidth() - width ) > Math::MACHINE_EPSILON_1000 ) )
+          {
+            controller->SetOutlineWidth( width );
+            update = true;
+          }
+        }
+        else
+        {
+          // Disable outline
+          if( fabsf( controller->GetOutlineWidth() ) > Math::MACHINE_EPSILON_1000 )
+          {
+            controller->SetOutlineWidth( 0.0f );
+            update = true;
+          }
+        }
         break;
       }
       case EffectStyle::INPUT:
       {
-        // Stores the input outline's properties string to be recovered by the GetOutlineProperties() function.
-        controller->SetInputOutlineProperties( properties );
+        const std::string& outlineProperties = value.Get<std::string>();
+
+        controller->SetInputOutlineProperties( outlineProperties );
         break;
       }
-    }
-  }
+    } // switch
+  } // if( controller )
 
   return update;
 }
@@ -493,7 +563,21 @@ void GetOutlineProperties( ControllerPtr controller, Property::Value& value, Eff
     {
       case EffectStyle::DEFAULT:
       {
-        value = controller->GetDefaultOutlineProperties();
+        const Vector4& color = controller->GetOutlineColor();
+        const float width = controller->GetOutlineWidth();
+
+        Property::Map map;
+
+        std::string colorStr;
+        Vector4ToColorString( color, colorStr );
+        map.Insert( COLOR_KEY, colorStr );
+
+        std::string widthStr;
+        FloatToString( width, widthStr );
+        map.Insert( WIDTH_KEY, widthStr );
+
+        value = map;
+
         break;
       }
       case EffectStyle::INPUT:
old mode 100644 (file)
new mode 100755 (executable)
index 4ab61a3..521f52c
@@ -72,6 +72,21 @@ bool ParseUnderlineProperties( const Property::Map& underlineProperties,
                                float& height );
 
 /**
+ * @brief Parses the outline properties.
+ *
+ * @param[in] outlineProperties The map with the outline properties.
+ * @param[out] colorDefined Whether the outline's color is defined.
+ * @param[out] color The outline's color.
+ * @param[out] widthDefined Whether the outline's width is defined.
+ * @param[out] width The outline's width.
+ */
+bool ParseOutlineProperties( const Property::Map& outlineProperties,
+                               bool& colorDefined,
+                               Vector4& color,
+                               bool& widthDefined,
+                               float& width );
+
+/**
  * @brief Sets the underline properties.
  *
  * @param[in] controller The text's controller.
index 8978beb..927f277 100644 (file)
@@ -45,10 +45,6 @@ const std::string TYPE_KEY( "type" );
 
 const std::string SYSTEM_TOKEN( "system" );
 
-#if defined(DEBUG_ENABLED)
-Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_CONTROLS");
-#endif
-
 } // namespace
 
 void SetFontFamilyProperty( ControllerPtr controller, const Property::Value& value )
old mode 100644 (file)
new mode 100755 (executable)
index 38e1fa2..18cb7cc
@@ -210,6 +210,21 @@ public:
    * @param[in] numberOfRuns Number of underline runs to be copied.
    */
   virtual void GetUnderlineRuns( GlyphRun* underlineRuns, UnderlineRunIndex index, Length numberOfRuns ) const = 0;
+
+  /**
+   * @brief Retrieve the outline color.
+   *
+   * @return The outline color.
+   */
+  virtual const Vector4& GetOutlineColor() const = 0;
+
+  /**
+   * @brief Retrieves the width of an outline
+   *
+   * @return The width of the outline.
+   */
+  virtual float GetOutlineWidth() const = 0;
+
 };
 
 } // namespace Text
old mode 100644 (file)
new mode 100755 (executable)
index 2c00cf8..cf6f35c
@@ -147,6 +147,16 @@ void Model::GetUnderlineRuns( GlyphRun* underlineRuns, UnderlineRunIndex index,
   mVisualModel->GetUnderlineRuns( underlineRuns, index, numberOfRuns );
 }
 
+const Vector4& Model::GetOutlineColor() const
+{
+  return mVisualModel->GetOutlineColor();
+}
+
+float Model::GetOutlineWidth() const
+{
+  return mVisualModel->GetOutlineWidth();
+}
+
 Model::Model()
 : mLogicalModel(),
   mVisualModel(),
old mode 100644 (file)
new mode 100755 (executable)
index a7b0bb8..cd49581
@@ -174,6 +174,16 @@ public:
    */
   virtual void GetUnderlineRuns( GlyphRun* underlineRuns, UnderlineRunIndex index, Length numberOfRuns ) const;
 
+  /**
+   * @copydoc ModelInterface::GetOutlineColor()
+   */
+  virtual const Vector4& GetOutlineColor() const;
+
+  /**
+   * @copydoc ModelInterface::GetOutlineWidth()
+   */
+  virtual float GetOutlineWidth() const;
+
 private: // Private contructors & copy operator.
 
   /**
old mode 100644 (file)
new mode 100755 (executable)
index 1b114c4..3e3f2d6
@@ -350,6 +350,11 @@ void VisualModel::SetUnderlineColor( const Vector4& color )
   mUnderlineColorSet = true;
 }
 
+void VisualModel::SetOutlineColor( const Vector4& color )
+{
+  mOutlineColor = color;
+}
+
 void VisualModel::SetUnderlineEnabled( bool enabled )
 {
   mUnderlineEnabled = enabled;
@@ -360,6 +365,11 @@ void VisualModel::SetUnderlineHeight( float height )
   mUnderlineHeight = height;
 }
 
+void VisualModel::SetOutlineWidth( float width )
+{
+  mOutlineWidth = width;
+}
+
 const Vector4& VisualModel::GetTextColor() const
 {
   return mTextColor;
@@ -380,6 +390,11 @@ const Vector4& VisualModel::GetUnderlineColor() const
   return mUnderlineColor;
 }
 
+const Vector4& VisualModel::GetOutlineColor() const
+{
+  return mOutlineColor;
+}
+
 bool VisualModel::IsUnderlineEnabled() const
 {
   return mUnderlineEnabled;
@@ -390,6 +405,11 @@ float VisualModel::GetUnderlineHeight() const
   return mUnderlineHeight;
 }
 
+float VisualModel::GetOutlineWidth() const
+{
+  return mOutlineWidth;
+}
+
 Length VisualModel::GetNumberOfUnderlineRuns() const
 {
   return mUnderlineRuns.Count();
@@ -415,9 +435,11 @@ VisualModel::VisualModel()
   mTextColor( Color::BLACK ),
   mShadowColor( Color::BLACK ),
   mUnderlineColor( Color::BLACK ),
+  mOutlineColor( Color::WHITE ),
   mControlSize(),
   mShadowOffset(),
   mUnderlineHeight( 0.0f ),
+  mOutlineWidth( 0.0f ),
   mNaturalSize(),
   mLayoutSize(),
   mCachedLineIndex( 0u ),
old mode 100644 (file)
new mode 100755 (executable)
index 6356f32..ea888cd
@@ -287,6 +287,34 @@ public:
    */
   Length GetNumberOfUnderlineRuns() const;
 
+  /**
+   * @brief Set the outline color.
+   *
+   * @param[in] color color of outline.
+   */
+  void SetOutlineColor( const Vector4& color );
+
+  /**
+   * @brief Retrieve the outline color.
+   *
+   * @return The outline color.
+   */
+  const Vector4& GetOutlineColor() const;
+
+  /**
+   * @brief Set the outline width
+   *
+   * @param[in] width The width in pixels of the outline, 0 indicates no outline
+   */
+  void SetOutlineWidth( float width );
+
+  /**
+   * @brief Retrieves the width of an outline
+   *
+   * @return The width of the outline.
+   */
+  float GetOutlineWidth() const;
+
 protected:
 
   /**
@@ -323,9 +351,11 @@ public:
   Vector4                mTextColor;            ///< The text color
   Vector4                mShadowColor;          ///< Color of drop shadow
   Vector4                mUnderlineColor;       ///< Color of underline
+  Vector4                mOutlineColor;         ///< Color of outline
   Size                   mControlSize;          ///< The size of the UI control.
   Vector2                mShadowOffset;         ///< Offset for drop shadow, 0 indicates no shadow
   float                  mUnderlineHeight;      ///< Fixed height for underline to override font metrics.
+  float                  mOutlineWidth;         ///< Width of outline.
 
 private:
 
old mode 100644 (file)
new mode 100755 (executable)
index c90c727..4031f94
@@ -586,6 +586,7 @@ void TextVisual::UpdateRenderer()
       }
 
       // 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 )
@@ -593,9 +594,16 @@ void TextVisual::UpdateRenderer()
         shadowEnabled = true;
       }
 
+      bool outlineWidthEnabled = false;
+      float outlineWidth = mController->GetTextModel()->GetOutlineWidth();
+      if ( outlineWidth > Math::MACHINE_EPSILON_1 )
+      {
+        outlineWidthEnabled = true;
+      }
+
       const bool underlineEnabled = mController->GetTextModel()->IsUnderlineEnabled();
 
-      if ( hasMultipleTextColors || containsEmoji || shadowEnabled || underlineEnabled )
+      if ( hasMultipleTextColors || containsEmoji || shadowEnabled || underlineEnabled || outlineWidthEnabled )
       {
         // Create RGBA textures if the text contains emojis or styles or multiple text colors
 
index cc78eff..1edcdb5 100644 (file)
@@ -31,7 +31,7 @@ namespace Toolkit
 
 const unsigned int TOOLKIT_MAJOR_VERSION = 1;
 const unsigned int TOOLKIT_MINOR_VERSION = 2;
-const unsigned int TOOLKIT_MICRO_VERSION = 57;
+const unsigned int TOOLKIT_MICRO_VERSION = 58;
 const char * const TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index b46e4ff..8b2bb60 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali-toolkit
 Summary:    Dali 3D engine Toolkit
-Version:    1.2.56
+Version:    1.2.58
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT