[dali_2.0.1] Merge branch 'devel/master' 12/247712/1
authorCheng-Shiun Tsai <cheng.tsai@samsung.com>
Fri, 13 Nov 2020 14:54:21 +0000 (14:54 +0000)
committerCheng-Shiun Tsai <cheng.tsai@samsung.com>
Fri, 13 Nov 2020 14:54:21 +0000 (14:54 +0000)
Change-Id: Ie63f92d9f407f46ca66006c6eb2c13d7d422bb16

40 files changed:
automated-tests/patch-coverage.pl
automated-tests/scripts/retriever.sh
automated-tests/scripts/tctestsgen.sh
automated-tests/src/dali-toolkit-internal/CMakeLists.txt
automated-tests/src/dali-toolkit-internal/utc-Dali-Dictionary.cpp [new file with mode: 0644]
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-gl-abstraction.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-gl-abstraction.h
automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp
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
automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp
automated-tests/src/dali-toolkit/utc-Dali-VisualFactory.cpp
dali-toolkit/devel-api/controls/text-controls/text-editor-devel.h
dali-toolkit/devel-api/controls/text-controls/text-field-devel.h
dali-toolkit/devel-api/controls/text-controls/text-label-devel.h
dali-toolkit/internal/builder/dictionary.h
dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp
dali-toolkit/internal/controls/text-controls/text-field-impl.cpp
dali-toolkit/internal/controls/text-controls/text-label-impl.cpp
dali-toolkit/internal/image-loader/image-load-thread.cpp
dali-toolkit/internal/text/text-controller-impl.cpp
dali-toolkit/internal/text/text-controller-impl.h
dali-toolkit/internal/text/text-controller-input-font-handler.cpp
dali-toolkit/internal/text/text-controller.cpp
dali-toolkit/internal/text/text-controller.h
dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp
dali-toolkit/internal/visuals/arc/arc-visual.cpp
dali-toolkit/internal/visuals/border/border-visual.cpp
dali-toolkit/internal/visuals/color/color-visual.cpp
dali-toolkit/internal/visuals/gradient/gradient-visual.cpp
dali-toolkit/internal/visuals/image-visual-shader-factory.cpp
dali-toolkit/internal/visuals/image-visual-shader-factory.h
dali-toolkit/internal/visuals/image/image-visual.cpp
dali-toolkit/internal/visuals/svg/svg-visual.cpp
dali-toolkit/internal/visuals/texture-manager-impl.cpp
dali-toolkit/internal/visuals/visual-base-impl.cpp
dali-toolkit/internal/visuals/visual-base-impl.h
dali-toolkit/public-api/dali-toolkit-version.cpp
packaging/dali-toolkit.spec

index 3a97dac..b3cf098 100755 (executable)
@@ -1105,7 +1105,7 @@ sub calc_patch_coverage_percentage
     my $percent = 0;
     if($total_exec > 0) { $percent = 100 * $total_covered_lines / $total_exec; }
 
-    return [ $total_exec, $percent ];
+    return [ $total_exec, $percent, $total_covered_lines ];
 }
 
 #
@@ -1417,6 +1417,7 @@ elsif( ! $opt_quiet )
     print RESET;
 }
 
+printf("Line Coverage: %d/%d\n", $percentref->[2], $percentref->[0]);
 printf("Percentage of change covered: %5.2f%\n", $percent);
 
 exit($percent<90);
index 248481e..102bb44 100755 (executable)
@@ -165,8 +165,8 @@ function tc_fullinfo {
     ' $*
 }
 
-TEMP=`getopt -o f,a:,m: --long full,anum:,mnum: \
-     -n 'genmake' -- "$@"`
+TEMP=`getopt -o f::,a:,m: --long full::,anum:,mnum: \
+     -n 'retriever.sh' -- "$@"`
 
 if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
 
@@ -174,12 +174,13 @@ if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
 eval set -- "$TEMP"
 
 opt_full=false
+opt_full_dir=
 opt_anum=
 opt_mnum=
 
 while true ; do
     case "$1" in
-        -f|--full) opt_full=true ; shift ;;
+        -f|--full) opt_full_dir="$2" ; opt_full="true" ; shift 2 ;;
         -a|--anum) opt_anum="$2" ; shift 2 ;;
         -m|--mnum) opt_mnum="$2" ; shift 2 ;;
         --) shift ; break ;;
@@ -187,6 +188,10 @@ while true ; do
     esac
 done
 
+#echo "###Retriever" >& 2
+#echo opt_full: {$opt_full} >& 2
+#echo opt_full_dir: {$opt_full_dir} >& 2
+
 DIR=.
 if [ -n "$opt_anum" ] ; then
     DIR=$opt_anum
@@ -194,8 +199,14 @@ if [ -n "$opt_anum" ] ; then
 elif [ -n "$opt_mnum" ] ; then
     DIR=$opt_mnum
     echo opt_mnum: DIR=$DIR >& 2
+elif [ "$opt_full" == "true" ] ; then
+    if [ -n $opt_full_dir ] ; then
+        DIR=$opt_full_dir
+        echo opt_full: DIR=$DIR >& 2
+    fi
 fi
 
+
 # get filename from first argument
 if [[ $# == 1 && -f $DIR/$1 ]] ; then
     FILE=$1
@@ -229,7 +240,7 @@ fi
 
 
 # run appropriate subcommand
-if [ $opt_full == "true" ] ; then
+if [ "$opt_full" == "true" ] ; then
     tc_fullinfo $TC_FILES
 elif [ -n "$opt_anum" ] ; then
     tc_anum $TC_FILES
index 1881668..517cfb4 100755 (executable)
@@ -60,7 +60,9 @@ print "</test_definition>"
     }' $TFILE > $FILE
 }
 
-(cd $SCRIPT_DIR/..; scripts/retriever.sh -f src/$MODULE_NAME $4 > ${TFILE}_pre)
+cmd="cd $SCRIPT_DIR/..; scripts/retriever.sh -fsrc/$MODULE_NAME $4 > ${TFILE}_pre"
+echo "$cmd"
+( eval $cmd )
 if [ $? -ne 0 ]; then cat ${TFILE}_pre; exit 1; fi
 cat ${TFILE}_pre | sort -t',' -k2,2 -s > $TFILE
 gen
index 5ff5890..ddd196c 100755 (executable)
@@ -12,6 +12,7 @@ SET(TC_SOURCES
  utc-Dali-ColorConversion.cpp
  utc-Dali-Control-internal.cpp
  utc-Dali-DebugRendering.cpp
+ utc-Dali-Dictionary.cpp
  utc-Dali-FeedbackStyle.cpp
  utc-Dali-ItemView-internal.cpp
  utc-Dali-LogicalModel.cpp
diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-Dictionary.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-Dictionary.cpp
new file mode 100644 (file)
index 0000000..698377e
--- /dev/null
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2020 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.
+ */
+
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <dali-toolkit/internal/builder/dictionary.h>
+using namespace Dali::Toolkit::Internal;
+
+
+std::string_view test_keys[20] =
+{
+  "testkey0", "testkey1", "testkey2", "testkey3", "testkey4", "testkey5", "testkey6", "testkey7", "testkey8", "testkey9",
+  "testkey10", "testkey11", "testkey12", "testkey13", "testkey14", "testkey15", "testkey16", "testkey17", "testkey18", "testkey19"
+};
+
+std::string_view testKeys[20] =
+{
+  "TestKey0", "TestKey1", "TestKey2", "TestKey3", "TestKey4", "TestKey5", "TestKey6", "TestKey7", "TestKey8", "TestKey9",
+  "TestKey10", "TestKey11", "TestKey12", "TestKey13", "TestKey14", "TestKey15", "TestKey16", "TestKey17", "TestKey18", "TestKey19"
+};
+
+
+int UtcDaliBuilderDictionaryNew(void)
+{
+  Dictionary<int> dictionary;
+
+  DictionaryKeys keys;
+  dictionary.GetKeys(keys);
+
+  DALI_TEST_CHECK( keys.empty() );
+  DALI_TEST_EQUALS( keys.size(), 0, TEST_LOCATION );
+  END_TEST;
+}
+
+
+int UtcDaliBuilderDictionaryAdd1(void)
+{
+  Dictionary<int> dictionary;
+
+  for(int i=0; i<10; i++)
+  {
+    char buffer[16];
+    sprintf(buffer, "testkey%d",i);
+    bool added=false;
+    if(i%2 == 0)
+    {
+      added = dictionary.Add(std::string(buffer), i);
+    }
+    else
+    {
+      added = dictionary.Add(buffer, i);
+    }
+    DALI_TEST_EQUALS(added, true, TEST_LOCATION);
+  }
+
+  DictionaryKeys keys;
+  dictionary.GetKeys(keys);
+
+  DALI_TEST_EQUALS( keys.size(), 10, TEST_LOCATION );
+  for(int i=0; i<10; i++)
+  {
+    char buffer[16];
+    sprintf(buffer, "testkey%d",i);
+    auto iter = std::find(keys.begin(), keys.end(), std::string(buffer));
+    DALI_TEST_CHECK(iter != keys.end());
+  }
+
+  END_TEST;
+}
+
+int UtcDaliBuilderDictionaryAdd2(void)
+{
+  Dictionary<int> dictionary;
+
+  for(int i=0; i<10; i++)
+  {
+    char buffer[16];
+    sprintf(buffer, "testkey%d",i);
+    bool added=false;
+    if(i%2 == 0)
+    {
+      added = dictionary.Add(std::string(buffer), i);
+    }
+    else
+    {
+      added = dictionary.Add(buffer, i);
+    }
+    DALI_TEST_EQUALS(added, true, TEST_LOCATION);
+  }
+
+  DictionaryKeys keys;
+  dictionary.GetKeys(keys);
+  DALI_TEST_EQUALS( keys.size(), 10, TEST_LOCATION );
+
+  bool added = dictionary.Add("testkey5", 1);
+  DALI_TEST_EQUALS(added, false, TEST_LOCATION);
+  DALI_TEST_EQUALS(*dictionary.Find("testkey5"), 5, TEST_LOCATION);
+
+  dictionary.Clear();
+  DALI_TEST_EQUALS(dictionary.Begin()==dictionary.End(), true, TEST_LOCATION);
+  dictionary.GetKeys(keys);
+  DALI_TEST_EQUALS( keys.size(), 0, TEST_LOCATION );
+
+  END_TEST;
+}
+
+
+int UtcDaliBuilderDictionaryRemoveP(void)
+{
+  Dictionary<int> dictionary;
+
+  for(int i=0; i<10; i++)
+  {
+    bool added=false;
+    added = dictionary.Add(std::string(testKeys[i]), i);
+    DALI_TEST_EQUALS(added, true, TEST_LOCATION);
+  }
+
+  DictionaryKeys keys;
+  dictionary.GetKeys(keys);
+  DALI_TEST_EQUALS( keys.size(), 10, TEST_LOCATION );
+
+  for(int i=0; i<10; i++)
+  {
+    if(i%2==0)
+    {
+      dictionary.Remove(test_keys[i]); // Should fail (case sensitive)
+    }
+    else
+    {
+      dictionary.Remove(testKeys[i]);
+    }
+  }
+  dictionary.GetKeys(keys);
+  DALI_TEST_EQUALS( keys.size(), 5, TEST_LOCATION );
+
+  dictionary.Clear();
+  DALI_TEST_EQUALS(dictionary.Begin()==dictionary.End(), true, TEST_LOCATION);
+  dictionary.GetKeys(keys);
+  DALI_TEST_EQUALS( keys.size(), 0, TEST_LOCATION );
+
+  END_TEST;
+}
+
+
+int UtcDaliBuilderDictionaryRemoveN(void)
+{
+  Dictionary<int> dictionary;
+
+  for(int i=0; i<10; i++)
+  {
+    bool added=false;
+    added = dictionary.Add(std::string(testKeys[i]), i);
+    DALI_TEST_EQUALS(added, true, TEST_LOCATION);
+  }
+
+  DictionaryKeys keys;
+  dictionary.GetKeys(keys);
+  DALI_TEST_EQUALS( keys.size(), 10, TEST_LOCATION );
+
+  dictionary.Remove("randomkey");
+  dictionary.GetKeys(keys);
+  DALI_TEST_EQUALS( keys.size(), 10, TEST_LOCATION );
+
+  END_TEST;
+}
+
+
+int UtcDaliBuilderDictionaryMerge1(void)
+{
+  // Test that "overlapping" dicts merge into 1 successfully
+  Dictionary<int> dictionary1;
+
+  for(int i=0; i<10; i++)
+  {
+    dictionary1.Add(std::string(test_keys[i]), i);
+  }
+
+  Dictionary<int> dictionary2;
+  for(int i=0; i<20; i++)
+  {
+    dictionary2.Add(std::string(testKeys[i]), i);
+  }
+
+  dictionary1.Merge(dictionary2);
+  DictionaryKeys keys;
+  dictionary1.GetKeys(keys);
+  DALI_TEST_EQUALS( keys.size(), 30, TEST_LOCATION ); // Now have 2 case versions of 10 keys :/ - broken by design?
+
+  for(int i=0; i<20;++i)
+  {
+    // Check both cases of keys
+    auto ptr1 = dictionary1.FindConst(test_keys[i]);
+    auto ptr2 = dictionary1.FindConst(testKeys[i]);
+
+    DALI_TEST_CHECK( nullptr != ptr1 );
+    DALI_TEST_CHECK( nullptr != ptr2 );
+  }
+
+  END_TEST;
+}
+
+int UtcDaliBuilderDictionaryMerge2(void)
+{
+  // Test that non-overlapping dicts merge successfully
+  Dictionary<int> dictionary1;
+  for(int i=0; i<10; i++) // Add first 10 from lowercase keys
+  {
+    dictionary1.Add(std::string(test_keys[i]), i);
+  }
+
+  Dictionary<int> dictionary2;
+  for(int i=10; i<20; i++) // add last 10 from capitalized keys
+  {
+    dictionary2.Add(std::string(testKeys[i]), i);
+  }
+
+  dictionary1.Merge(dictionary2);
+  DictionaryKeys keys;
+  dictionary1.GetKeys(keys);
+  DALI_TEST_EQUALS( keys.size(), 20, TEST_LOCATION ); // check it's an amalgam of both
+
+  for(int i=0; i<20;++i)
+  {
+    // Check both cases of keys
+    DALI_TEST_CHECK( nullptr != dictionary1.FindConst(test_keys[i]));
+    DALI_TEST_CHECK( nullptr != dictionary1.FindConst(testKeys[i]));
+  }
+
+  END_TEST;
+}
+
+
+template<typename EntryType>
+struct TestElement
+{
+  std::string key;
+  EntryType entry;
+  TestElement(std::string name, EntryType entry)
+  : key(std::move(name)),
+    entry(std::move(entry))
+  {
+  }
+};
+
+int UtcDaliBuilderDictionaryFindP(void)
+{
+  // Test that non-overlapping dicts merge successfully
+  Dictionary<int> dictionary;
+  for(int i=0; i<10; i++) // Add first 10 from lowercase keys
+  {
+    dictionary.Add(std::string(test_keys[i]), i);
+  }
+
+  // Test that the entries can be directly modified
+  for(int i=0; i<10; i++)
+  {
+    auto entryPtr = dictionary.Find(testKeys[i]);
+    DALI_TEST_CHECK( entryPtr != nullptr );
+    *entryPtr = i+10;
+  }
+
+  for(int i=0; i<10; ++i)
+  {
+    auto entryPtr = dictionary.Find(testKeys[i]);
+    DALI_TEST_CHECK( entryPtr != nullptr );
+    DALI_TEST_EQUALS( *entryPtr, i+10, TEST_LOCATION );
+  }
+
+  END_TEST;
+}
index a694eeb..9e8c7a8 100644 (file)
@@ -112,6 +112,31 @@ bool TestGlAbstraction::IsSurfacelessContextSupported() const
   return true;
 }
 
+bool TestGlAbstraction::IsAdvancedBlendEquationSupported()
+{
+  return true;
+}
+
+bool TestGlAbstraction::IsBlendEquationSupported(DevelBlendEquation::Type blendEquation)
+{
+  return true;
+}
+
+std::string TestGlAbstraction::GetShaderVersionPrefix()
+{
+  return std::string("");
+}
+
+std::string TestGlAbstraction::GetVertexShaderPrefix()
+{
+  return std::string("");
+}
+
+std::string TestGlAbstraction::GetFragmentShaderPrefix()
+{
+  return std::string("");
+}
+
 bool TestGlAbstraction::TextureRequiresConverting(const GLenum imageGlFormat, const GLenum textureGlFormat, const bool isSubImage) const
 {
   return ((imageGlFormat == GL_RGB) && (textureGlFormat == GL_RGBA));
index 99dca10..861f4ae 100644 (file)
@@ -61,6 +61,16 @@ public:
 
   bool IsSurfacelessContextSupported() const override;
 
+  bool IsAdvancedBlendEquationSupported() override;
+
+  bool IsBlendEquationSupported(DevelBlendEquation::Type blendEquation) override;
+
+  std::string GetShaderVersionPrefix();
+
+  std::string GetVertexShaderPrefix();
+
+  std::string GetFragmentShaderPrefix();
+
   bool TextureRequiresConverting(const GLenum imageGlFormat, const GLenum textureGlFormat, const bool isSubImage) const override;
 
   /* OpenGL ES 2.0 */
@@ -1889,6 +1899,10 @@ public:
   {
   }
 
+  inline void BlendBarrier(void)
+  {
+  }
+
 private:
   inline void AddUniformCallToTraceStack(GLint location, std::string& value)
   {
index f31da7c..2be7c5a 100644 (file)
@@ -2766,9 +2766,21 @@ void OnResourceReadySignal( Control control )
   }
 }
 
+void OnResourceReadySignal01( Control control )
+{
+  if(++gResourceReadySignalCounter == 1)
+  {
+    // It makes the first new visual be deleted immediately
+    // The first image will not be loaded.
+    control[ImageView::Property::IMAGE] = Property::Map().Add(ImageVisual::Property::URL, gImage_600_RGB)
+                                                         .Add(ImageVisual::Property::RELEASE_POLICY, ImageVisual::ReleasePolicy::NEVER);
+    control[ImageView::Property::IMAGE] = TEST_IMAGE_1;
+  }
+}
+
 }
 
-int UtcDaliImageViewSetImageOnResourceReadySignal(void)
+int UtcDaliImageViewSetImageOnResourceReadySignal01(void)
 {
   tet_infoline("Test setting image from within signal handler.");
 
@@ -2809,3 +2821,31 @@ int UtcDaliImageViewSetImageOnResourceReadySignal(void)
 
   END_TEST;
 }
+
+int UtcDaliImageViewSetImageOnResourceReadySignal02(void)
+{
+  tet_infoline("Test setting image from within signal handler.");
+
+  ToolkitTestApplication application;
+
+  gResourceReadySignalCounter = 0;
+
+  ImageView imageView = ImageView::New( gImage_34_RGBA );
+  imageView.ResourceReadySignal().Connect( &OnResourceReadySignal01 );
+
+  application.GetScene().Add( imageView );
+
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  // Wait for loading an image
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( gResourceReadySignalCounter, 2, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( imageView.IsResourceReady(), true, TEST_LOCATION );
+
+  END_TEST;
+}
index 49e630d..8fb86da 100644 (file)
@@ -102,6 +102,7 @@ const char* const PROPERTY_NAME_ENABLE_SHIFT_SELECTION               = "enableSh
 const char* const PROPERTY_NAME_ENABLE_GRAB_HANDLE                   = "enableGrabHandle";
 const char* const PROPERTY_NAME_MATCH_SYSTEM_LANGUAGE_DIRECTION      = "matchSystemLanguageDirection";
 const char* const PROPERTY_NAME_MAX_LENGTH                           = "maxLength";
+const char* const PROPERTY_NAME_FONT_SIZE_SCALE                      = "fontSizeScale";
 
 
 const Vector4 PLACEHOLDER_TEXT_COLOR( 0.8f, 0.8f, 0.8f, 0.8f );
@@ -487,6 +488,7 @@ int UtcDaliTextEditorGetPropertyP(void)
   DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_LINE_COUNT) == TextEditor::Property::LINE_COUNT );
   DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_ENABLE_SELECTION ) == TextEditor::Property::ENABLE_SELECTION );
   DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_PLACEHOLDER ) == TextEditor::Property::PLACEHOLDER );
+  DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_FONT_SIZE_SCALE ) == DevelTextEditor::Property::FONT_SIZE_SCALE );
   DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_PLACEHOLDER_TEXT ) == DevelTextEditor::Property::PLACEHOLDER_TEXT );
   DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_PLACEHOLDER_TEXT_COLOR ) == DevelTextEditor::Property::PLACEHOLDER_TEXT_COLOR );
   DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_ENABLE_SHIFT_SELECTION ) == DevelTextEditor::Property::ENABLE_SHIFT_SELECTION );
@@ -494,6 +496,7 @@ int UtcDaliTextEditorGetPropertyP(void)
   DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_MATCH_SYSTEM_LANGUAGE_DIRECTION ) == DevelTextEditor::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION );
   DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_MAX_LENGTH ) == DevelTextEditor::Property::MAX_LENGTH );
 
+
   END_TEST;
 }
 
@@ -558,6 +561,10 @@ int UtcDaliTextEditorSetPropertyP(void)
   editor.SetProperty( TextEditor::Property::POINT_SIZE, 10.f );
   DALI_TEST_EQUALS( editor.GetProperty<float>( TextEditor::Property::POINT_SIZE ), 10.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
 
+  editor.SetProperty( DevelTextEditor::Property::FONT_SIZE_SCALE, 2.5f );
+  DALI_TEST_EQUALS( editor.GetProperty<float>( DevelTextEditor::Property::FONT_SIZE_SCALE ), 2.5f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+  editor.SetProperty( DevelTextEditor::Property::FONT_SIZE_SCALE, 1.0f );
+
   // Reset font style.
   fontStyleMapSet.Clear();
   fontStyleMapSet.Insert( "weight", "normal" );
@@ -3131,3 +3138,35 @@ int UtcDaliTextEditorScrolling(void)
 
   END_TEST;
 }
+
+int UtcDaliToolkitTextEditorFontSizeScale(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextEditorFontSizeScale");
+
+  TextEditor textEditor = TextEditor::New();
+  textEditor.SetProperty( TextEditor::Property::POINT_SIZE, 30.f );
+  textEditor.SetProperty( TextEditor::Property::TEXT, "Test" );
+  Vector3 nonScaledSize = textEditor.GetNaturalSize();
+
+  TextEditor textEditorScaled = TextEditor::New();
+  textEditorScaled.SetProperty( TextEditor::Property::POINT_SIZE, 15.f );
+  textEditorScaled.SetProperty( Toolkit::DevelTextEditor::Property::FONT_SIZE_SCALE, 2.f );
+  textEditorScaled.SetProperty( TextEditor::Property::TEXT, "Test" );
+  Vector3 scaledSize = textEditorScaled.GetNaturalSize();
+
+  DALI_TEST_EQUALS( nonScaledSize, scaledSize, TEST_LOCATION );
+
+  textEditor.SetProperty( TextEditor::Property::PIXEL_SIZE, 30.f );
+  textEditor.SetProperty( TextEditor::Property::TEXT, "Test" );
+  nonScaledSize = textEditor.GetNaturalSize();
+
+  textEditorScaled.SetProperty( TextEditor::Property::PIXEL_SIZE, 15.f );
+  textEditorScaled.SetProperty( Toolkit::DevelTextEditor::Property::FONT_SIZE_SCALE, 2.f );
+  textEditorScaled.SetProperty( TextEditor::Property::TEXT, "Test" );
+  scaledSize = textEditorScaled.GetNaturalSize();
+
+  DALI_TEST_EQUALS( nonScaledSize, scaledSize, TEST_LOCATION );
+
+  END_TEST;
+}
index 2dd61c2..b3b4412 100644 (file)
@@ -104,6 +104,7 @@ const char* const PROPERTY_NAME_ENABLE_GRAB_HANDLE                   = "enableGr
 const char* const PROPERTY_NAME_MATCH_SYSTEM_LANGUAGE_DIRECTION      = "matchSystemLanguageDirection";
 const char* const PROPERTY_NAME_ENABLE_GRAB_HANDLE_POPUP             = "enableGrabHandlePopup";
 const char* const PROPERTY_NAME_BACKGROUND                           = "textBackground";
+const char* const PROPERTY_NAME_FONT_SIZE_SCALE                      = "fontSizeScale";
 
 const Vector4 PLACEHOLDER_TEXT_COLOR( 0.8f, 0.8f, 0.8f, 0.8f );
 const Dali::Vector4 LIGHT_BLUE( 0.75f, 0.96f, 1.f, 1.f ); // The text highlight color.
@@ -503,6 +504,7 @@ int UtcDaliTextFieldGetPropertyP(void)
   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_ENABLE_SELECTION ) == TextField::Property::ENABLE_SELECTION );
   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_PLACEHOLDER ) == TextField::Property::PLACEHOLDER );
   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_ELLIPSIS ) == TextField::Property::ELLIPSIS );
+  DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_FONT_SIZE_SCALE ) == DevelTextField::Property::FONT_SIZE_SCALE );
   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_ENABLE_SHIFT_SELECTION ) == DevelTextField::Property::ENABLE_SHIFT_SELECTION );
   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_ENABLE_GRAB_HANDLE ) == DevelTextField::Property::ENABLE_GRAB_HANDLE );
   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_MATCH_SYSTEM_LANGUAGE_DIRECTION ) == DevelTextField::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION );
@@ -579,6 +581,10 @@ int UtcDaliTextFieldSetPropertyP(void)
   field.SetProperty( TextField::Property::POINT_SIZE, 10.f );
   DALI_TEST_EQUALS( field.GetProperty<float>( TextField::Property::POINT_SIZE ), 10.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
 
+  field.SetProperty( DevelTextField::Property::FONT_SIZE_SCALE, 2.5f );
+  DALI_TEST_EQUALS( field.GetProperty<float>( DevelTextField::Property::FONT_SIZE_SCALE ), 2.5f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+  field.SetProperty( DevelTextField::Property::FONT_SIZE_SCALE, 1.0f );
+
   // Reset font style.
   fontStyleMapSet.Clear();
   fontStyleMapSet.Insert( "weight", "normal" );
@@ -3050,3 +3056,35 @@ int UtcDaliTextFieldEnableEditing(void)
 
   END_TEST;
 }
+
+int UtcDaliToolkitTextFieldFontSizeScale(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextFieldFontSizeScale");
+
+  TextField textField = TextField::New();
+  textField.SetProperty( TextField::Property::POINT_SIZE, 30.f );
+  textField.SetProperty( TextField::Property::TEXT, "Test" );
+  Vector3 nonScaledSize = textField.GetNaturalSize();
+
+  TextField textFieldScaled = TextField::New();
+  textFieldScaled.SetProperty( TextField::Property::POINT_SIZE, 15.f );
+  textFieldScaled.SetProperty( Toolkit::DevelTextField::Property::FONT_SIZE_SCALE, 2.f );
+  textFieldScaled.SetProperty( TextField::Property::TEXT, "Test" );
+  Vector3 scaledSize = textFieldScaled.GetNaturalSize();
+
+  DALI_TEST_EQUALS( nonScaledSize, scaledSize, TEST_LOCATION );
+
+  textField.SetProperty( TextField::Property::PIXEL_SIZE, 30.f );
+  textField.SetProperty( TextField::Property::TEXT, "Test" );
+  nonScaledSize = textField.GetNaturalSize();
+
+  textFieldScaled.SetProperty( TextField::Property::PIXEL_SIZE, 15.f );
+  textFieldScaled.SetProperty( Toolkit::DevelTextField::Property::FONT_SIZE_SCALE, 2.f );
+  textFieldScaled.SetProperty( TextField::Property::TEXT, "Test" );
+  scaledSize = textFieldScaled.GetNaturalSize();
+
+  DALI_TEST_EQUALS( nonScaledSize, scaledSize, TEST_LOCATION );
+
+  END_TEST;
+}
index f9128fd..57862f4 100644 (file)
@@ -72,6 +72,7 @@ const char* const PROPERTY_NAME_BACKGROUND = "textBackground";
 const char* const PROPERTY_NAME_PIXEL_SIZE = "pixelSize";
 const char* const PROPERTY_NAME_ELLIPSIS = "ellipsis";
 const char* const PROPERTY_NAME_AUTO_SCROLL_LOOP_DELAY = "autoScrollLoopDelay";
+const char* const PROPERTY_NAME_FONT_SIZE_SCALE = "fontSizeScale";
 
 const std::string DEFAULT_FONT_DIR( "/resources/fonts" );
 const unsigned int EMOJI_FONT_SIZE = 3840u; // 60 * 64
@@ -310,6 +311,7 @@ int UtcDaliToolkitTextLabelGetPropertyP(void)
   DALI_TEST_CHECK( label.GetPropertyIndex( PROPERTY_NAME_PIXEL_SIZE ) == TextLabel::Property::PIXEL_SIZE );
   DALI_TEST_CHECK( label.GetPropertyIndex( PROPERTY_NAME_ELLIPSIS ) == TextLabel::Property::ELLIPSIS );
   DALI_TEST_CHECK( label.GetPropertyIndex( PROPERTY_NAME_AUTO_SCROLL_LOOP_DELAY ) == TextLabel::Property::AUTO_SCROLL_LOOP_DELAY );
+  DALI_TEST_CHECK( label.GetPropertyIndex( PROPERTY_NAME_FONT_SIZE_SCALE ) == DevelTextLabel::Property::FONT_SIZE_SCALE );
 
   END_TEST;
 }
@@ -361,6 +363,10 @@ int UtcDaliToolkitTextLabelSetPropertyP(void)
   label.SetProperty( TextLabel::Property::POINT_SIZE, 10.f );
   DALI_TEST_EQUALS( label.GetProperty<float>( TextLabel::Property::POINT_SIZE ), 10.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
 
+  label.SetProperty( DevelTextLabel::Property::FONT_SIZE_SCALE, 2.5f );
+  DALI_TEST_EQUALS( label.GetProperty<float>( DevelTextLabel::Property::FONT_SIZE_SCALE ), 2.5f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+  label.SetProperty( DevelTextLabel::Property::FONT_SIZE_SCALE, 1.0f );
+
   // Reset font style.
   fontStyleMapSet.Clear();
   fontStyleMapSet.Insert( "weight", "normal" );
@@ -1689,3 +1695,35 @@ int UtcDaliToolkitTextlabelLastCharacterIndex(void)
 
   END_TEST;
 }
+
+int UtcDaliToolkitTextlabelFontSizeScale(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextlabelFontSizeScale");
+
+  TextLabel label = TextLabel::New();
+  label.SetProperty( TextLabel::Property::POINT_SIZE, 30.f );
+  label.SetProperty( TextLabel::Property::TEXT, "Test" );
+  Vector3 nonScaledSize = label.GetNaturalSize();
+
+  TextLabel labelScaled = TextLabel::New();
+  labelScaled.SetProperty( TextLabel::Property::POINT_SIZE, 15.f );
+  labelScaled.SetProperty( Toolkit::DevelTextLabel::Property::FONT_SIZE_SCALE, 2.f );
+  labelScaled.SetProperty( TextLabel::Property::TEXT, "Test" );
+  Vector3 scaledSize = labelScaled.GetNaturalSize();
+
+  DALI_TEST_EQUALS( nonScaledSize, scaledSize, TEST_LOCATION );
+
+  label.SetProperty( TextLabel::Property::PIXEL_SIZE, 30.f );
+  label.SetProperty( TextLabel::Property::TEXT, "Test" );
+  nonScaledSize = label.GetNaturalSize();
+
+  labelScaled.SetProperty( TextLabel::Property::PIXEL_SIZE, 15.f );
+  labelScaled.SetProperty( Toolkit::DevelTextLabel::Property::FONT_SIZE_SCALE, 2.f );
+  labelScaled.SetProperty( TextLabel::Property::TEXT, "Test" );
+  scaledSize = labelScaled.GetNaturalSize();
+
+  DALI_TEST_EQUALS( nonScaledSize, scaledSize, TEST_LOCATION );
+
+  END_TEST;
+}
index 9823516..f17f120 100644 (file)
@@ -2817,6 +2817,23 @@ static void TestTransform( ToolkitTestApplication& application, Visual::Base vis
   DALI_TEST_EQUALS( extraSize, Vector2(0.5f,0.5f), TEST_LOCATION );
 }
 
+int UtcDaliVisualSetTransform01(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliVisualSetTransform: ColorVisual" );
+
+  VisualFactory factory = VisualFactory::Get();
+  Property::Map propertyMap;
+  propertyMap.Insert(Visual::Property::TYPE, Visual::COLOR);
+  propertyMap.Insert(Visual::Property::OPACITY, 0.5f);
+  propertyMap.Insert(ColorVisual::Property::MIX_COLOR, Color::BLUE);
+  Visual::Base visual = factory.CreateVisual( propertyMap );
+  TestTransform( application, visual );
+  TestMixColor( visual, ColorVisual::Property::MIX_COLOR, Color::BLUE );
+
+  END_TEST;
+}
+
 int UtcDaliVisualSetTransform0(void)
 {
   ToolkitTestApplication application;
index ad0dc43..faae3fe 100644 (file)
@@ -1131,9 +1131,9 @@ int UtcDaliVisualFactoryGetSvgVisual(void)
   application.GetScene().Add( actor );
   visual.SetTransformAndSize(DefaultTransform(), Vector2(200.f, 200.f) );
 
+  // Either application.SendNotification() or the trigger can now complete the task.
   application.SendNotification();
   application.Render();
-
   DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
 
   // renderer is added to actor
@@ -1167,9 +1167,9 @@ int UtcDaliVisualFactoryGetSvgVisualLarge(void)
   dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
   application.GetScene().Add( actor );
 
+  // Either application.SendNotification() or the trigger can now complete the task.
   application.SendNotification();
   application.Render();
-
   DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
 
   // renderer is added to actor
@@ -1210,12 +1210,10 @@ int UtcDaliVisualFactoryGetSvgVisualAtlas(void)
   application.GetScene().Add( actor );
   visual.SetTransformAndSize(DefaultTransform(), Vector2(200.f, 200.f) );
 
+  // Either application.SendNotification() or the trigger can now complete the task.
+  DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
   application.SendNotification();
   application.Render();
-
-  // renderer is not added to actor until the rasterization is completed.
-  DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
-
   DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
 
   // renderer is added to actor
index 6cb473c..9a5bff1 100644 (file)
@@ -163,6 +163,18 @@ enum Type
    * @note This property is read-only.
    */
   SELECTED_TEXT,
+
+  /**
+   * @brief The font size scale.
+   * @details name "fontSizeScale", type Property::FLOAT.
+   * @note The default value is 1.0 which does nothing.
+   * The given font size scale value is used for multiplying the specified font size before querying fonts.
+   *
+   * e.g. The rendering results of both cases are same.
+   *  - fontSize: 15pt, fontSizeScale: 1.0
+   *  - fontSize: 10pt, fontSizeScale: 1.5
+   */
+  FONT_SIZE_SCALE,
 };
 
 } // namespace Property
index cec1709..f13b2cb 100644 (file)
@@ -149,6 +149,18 @@ enum
    */
   ENABLE_EDITING,
 
+  /**
+   * @brief The font size scale.
+   * @details name "fontSizeScale", type Property::FLOAT.
+   * @note The default value is 1.0 which does nothing.
+   * The given font size scale value is used for multiplying the specified font size before querying fonts.
+   *
+   * e.g. The rendering results of both cases are same.
+   *  - fontSize: 15pt, fontSizeScale: 1.0
+   *  - fontSize: 10pt, fontSizeScale: 1.5
+   */
+  FONT_SIZE_SCALE
+
 };
 } // namespace Property
 
index a315536..9b3e4db 100644 (file)
@@ -142,6 +142,18 @@ enum Type
      * @details Name "renderingBackend", type Property::INT.
      */
   RENDERING_BACKEND,
+
+  /**
+   * @brief The font size scale for scaling the specified font size up or down.
+   * @details name "fontSizeScale", type Property::FLOAT.
+   * @note The default value is 1.0 which does nothing.
+   * The given font size scale value is used for multiplying the specified font size before querying fonts.
+   *
+   * e.g. The rendering results of both cases are same.
+   *  - fontSize: 15pt, fontSizeScale: 1.0
+   *  - fontSize: 10pt, fontSizeScale: 1.5
+   */
+  FONT_SIZE_SCALE,
 };
 
 } // namespace Property
index 65c7e18..a3036d9 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_BUILDER_DICTIONARY_H
 
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
@@ -39,17 +39,16 @@ namespace Internal
  * It enables lookup of keys via case-insensitive match.
  */
 
+using DictionaryKeys = std::vector<std::string>;
 
-typedef std::vector<std::string> DictionaryKeys;
 inline void Merge( DictionaryKeys& toDict, const DictionaryKeys& fromDict )
 {
-  for( DictionaryKeys::const_iterator fromIter = fromDict.begin(); fromIter != fromDict.end(); ++fromIter )
+  for(const auto& element : fromDict)
   {
-    const std::string& fromKey = (*fromIter);
-    DictionaryKeys::iterator toIter = std::find( toDict.begin(), toDict.end(), fromKey );
-    if( toIter == toDict.end() )
+    auto iter = std::find(toDict.cbegin(), toDict.cend(), element);
+    if(iter == toDict.cend())
     {
-      toDict.push_back( fromKey );
+      toDict.push_back(element);
     }
   }
 }
@@ -66,105 +65,97 @@ private:
   {
     std::string key;
     EntryType entry;
-    Element( const std::string&name, EntryType entry )
-    : key( name ),
-      entry( entry )
+    Element(std::string name, EntryType entry)
+    : key(std::move(name)),
+      entry(std::move(entry))
     {
     }
   };
-  typedef std::vector<Element> Elements;
+  using Elements = std::vector<Element>;
   Elements container;
 
+  auto FindElementCaseInsensitive(std::string_view key) const
+  {
+    return std::find_if(
+      Begin(), End(), [key](auto& e) { return Dali::CaseInsensitiveStringCompare(e.key, key); });
+  }
+
+  auto FindElement(std::string_view key)
+  {
+    return std::find_if(container.begin(), container.end(), [key](auto& e){
+        return bool(key == e.key);
+      });
+  }
+
 public:
   /**
    * Only allow const iteration over the dictionary
    */
-  typedef typename Elements::const_iterator iterator;
+  using iterator = typename Elements::const_iterator;
 
   /**
    * Constructor
    */
-  Dictionary<EntryType>()
-  {
-  }
+  Dictionary<EntryType>() = default;
 
   /**
    * Add a key value pair to the dictionary.
    * If the entry does not already exist, add it to the dictionary
-   * using a shallow copy
    */
-  bool Add( const std::string& name, const EntryType& entry )
+  bool Add(std::string name, EntryType entry)
   {
-    for( typename Elements::iterator iter = container.begin(); iter != container.end(); ++iter )
+    auto iter = FindElement(name);
+    if(iter != End())
     {
-      if( iter->key == name )
-      {
-        return false;
-      }
+      return false;
     }
-    container.push_back( Element(name, entry) );
+
+    container.push_back(Element(std::move(name), std::move(entry)));
     return true;
   }
 
   /**
    * Add a key-value pair to the dictionary
    * If the entry does not already exist, add it to the dictionary
-   * (shallow copy)
    */
-  bool Add( const char* name, const EntryType& entry )
+  bool Add(const char* name, EntryType entry)
   {
-    bool result=false;
-    if( name != NULL )
+    if(name != nullptr)
     {
-      std::string theName(name);
-      result=Add(theName, entry);
+      return Add(std::string(name), std::move(entry));
     }
-    return result;
+    return false;
   }
 
   /**
    * Remove a key value pair from the dictionary.
    */
-  void Remove( const std::string& name )
+  void Remove(std::string_view name)
   {
-    for( typename Elements::iterator iter = container.begin(); iter != container.end(); ++iter )
+    if(!name.empty())
     {
-      if( iter->key == name )
+      auto iter = FindElement(name);
+
+      if(iter != End())
       {
         container.erase( iter );
-        break;
       }
     }
   }
 
-  /**
-   * Remove a key value pair from the dictionary.
-   */
-  void Remove( const char* name )
-  {
-    if( name != NULL )
-    {
-      std::string theName(name);
-      Remove(theName);
-    }
-  }
-
   void Merge( const Dictionary<EntryType>& dictionary )
   {
-    for( typename Elements::const_iterator fromIter = dictionary.container.begin(); fromIter != dictionary.container.end(); ++fromIter )
+    for(const auto& element : dictionary.container)
     {
-      bool found=false;
-      for( typename Elements::iterator toIter = container.begin(); toIter != container.end(); ++toIter )
+      auto iter = FindElement(element.key);
+
+      if(iter == End())
       {
-        if( fromIter->key == toIter->key )
-        {
-          found=true;
-          toIter->entry = fromIter->entry;
-        }
+        container.push_back(Element(element.key, element.entry));
       }
-      if( !found )
+      else
       {
-        container.push_back( Element(fromIter->key, fromIter->entry) );
+        iter->entry = element.entry;
       }
     }
   }
@@ -173,92 +164,57 @@ public:
    * Find the element in the dictionary pointed at by key, and
    * insensitive search, and return a const pointer to it, or NULL
    */
-  const EntryType* FindConst( const std::string& key ) const
+  const EntryType* FindConst(std::string_view key) const
   {
     if( ! key.empty() )
     {
-      for( typename Elements::const_iterator iter = container.begin(); iter != container.end(); ++iter )
+      auto iter = FindElementCaseInsensitive(key);
+
+      if(iter != End())
       {
-        if( Dali::CaseInsensitiveStringCompare(iter->key, key ))
-        {
-          const EntryType* result = &(iter->entry);
-          return result;
-        }
+        return &(iter->entry);
       }
     }
-    return NULL;
+    return nullptr;
   }
 
   /**
    * Find the element in the dictionary pointed at by key using a case
    * insensitive search, and return a non-const pointer to it, or NULL
    */
-  EntryType* Find( const std::string& key ) const
+  EntryType* Find(std::string_view key) const
   {
-    EntryType* result = NULL;
     if( ! key.empty() )
     {
-      for( typename Elements::const_iterator iter = container.begin(); iter != container.end(); ++iter )
+      auto iter = FindElementCaseInsensitive(key);
+
+      if(iter != End())
       {
-        if( Dali::CaseInsensitiveStringCompare(iter->key, key ))
-        {
-          // Const cast because of const_iterator. const_iterator because, STL.
-          result = const_cast<EntryType*>(&(iter->entry));
-        }
+        return const_cast<EntryType*>(&(iter->entry));
       }
     }
-    return result;
-  }
-
-  /**
-   * Find the element in the dictionary pointed at by key using a case
-   * insensitive search, and return a const pointer to it, or NULL
-   */
-  const EntryType* FindConst( const char* key ) const
-  {
-    if( key != NULL )
-    {
-      std::string theKey(key);
-      return FindConst( theKey );
-    }
-    return NULL;
+    return nullptr;
   }
 
-  /**
-   * Find the element in the dictionary pointed at by key using a case
-   * insensitive search, and return a non-const pointer to it, or NULL
-   */
-  EntryType* Find( const char* key ) const
-  {
-    if( key != NULL )
-    {
-      std::string theKey(key);
-      return Find( theKey );
-    }
-    return NULL;
-  }
-  /**
-   * Return an iterator pointing at the first entry in the dictionary
-   */
-  typename Elements::const_iterator Begin() const
+  iterator Begin() const
   {
-    return container.begin();
+    return container.cbegin();
   }
 
   /**
    * Return an iterator pointing past the last entry in the dictionary
    */
-  typename Elements::const_iterator End() const
+  iterator End() const
   {
-    return container.end();
+    return container.cend();
   }
 
   void GetKeys( DictionaryKeys& keys ) const
   {
     keys.clear();
-    for( typename Elements::const_iterator iter = container.begin(); iter != container.end(); ++iter )
+    for(const auto& element : container)
     {
-      keys.push_back( (*iter).key );
+      keys.push_back(element.key);
     }
   }
 
index dc82c36..113a1f5 100644 (file)
@@ -147,6 +147,7 @@ DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "horizontalScrollPosition
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "verticalScrollPosition",         INTEGER,   VERTICAL_SCROLL_POSITION             )
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "enableEditing",                  BOOLEAN,   ENABLE_EDITING                       )
 DALI_DEVEL_PROPERTY_REGISTRATION_READ_ONLY( Toolkit, TextEditor, "selectedText",         STRING,    SELECTED_TEXT                        )
+DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "fontSizeScale",                  FLOAT,     FONT_SIZE_SCALE                      )
 
 DALI_SIGNAL_REGISTRATION( Toolkit, TextEditor, "textChanged",        SIGNAL_TEXT_CHANGED )
 DALI_SIGNAL_REGISTRATION( Toolkit, TextEditor, "inputStyleChanged",  SIGNAL_INPUT_STYLE_CHANGED )
@@ -744,6 +745,17 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P
         }
         break;
       }
+      case Toolkit::DevelTextEditor::Property::FONT_SIZE_SCALE:
+      {
+        const float scale = value.Get< float >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p FONT_SIZE_SCALE %f\n", impl.mController.Get(), scale );
+
+        if( !Equals( impl.mController->GetFontSizeScale(), scale ) )
+        {
+          impl.mController->SetFontSizeScale( scale );
+        }
+        break;
+      }
     } // switch
   } // texteditor
 }
@@ -1090,6 +1102,11 @@ Property::Value TextEditor::GetProperty( BaseObject* object, Property::Index ind
         value = impl.GetVerticalScrollPosition();
         break;
       }
+      case Toolkit::DevelTextEditor::Property::FONT_SIZE_SCALE:
+      {
+        value = impl.mController->GetFontSizeScale();
+        break;
+      }
     } //switch
   }
 
index 312a54e..1bf65ca 100644 (file)
@@ -138,6 +138,7 @@ DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "renderingBackend",
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "selectedTextStart",              INTEGER,   SELECTED_TEXT_START                  )
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "selectedTextEnd",                INTEGER,   SELECTED_TEXT_END                    )
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "enableEditing",                  BOOLEAN,   ENABLE_EDITING                       )
+DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "fontSizeScale",                  FLOAT,     FONT_SIZE_SCALE                      )
 
 DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "textChanged",        SIGNAL_TEXT_CHANGED )
 DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "maxLengthReached",   SIGNAL_MAX_LENGTH_REACHED )
@@ -733,6 +734,17 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
         impl.SetEditable( editable );
         break;
       }
+      case Toolkit::DevelTextField::Property::FONT_SIZE_SCALE:
+      {
+        const float scale = value.Get< float >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p FONT_SIZE_SCALE %f\n", impl.mController.Get(), scale );
+
+        if( !Equals( impl.mController->GetFontSizeScale(), scale ) )
+        {
+          impl.mController->SetFontSizeScale( scale );
+        }
+        break;
+      }
     } // switch
   } // textfield
 }
@@ -1073,6 +1085,11 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
         value = impl.IsEditable();
         break;
       }
+      case Toolkit::DevelTextField::Property::FONT_SIZE_SCALE:
+      {
+        value = impl.mController->GetFontSizeScale();
+        break;
+      }
     } //switch
   }
 
index 3ecb376..1c03203 100755 (executable)
@@ -134,6 +134,7 @@ DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit,     TextLabel, "matchSystemLanguageDi
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit,     TextLabel, "textFit",                   MAP,     TEXT_FIT                   )
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit,     TextLabel, "minLineSize",               FLOAT,   MIN_LINE_SIZE              )
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit,     TextLabel, "renderingBackend",          INTEGER, RENDERING_BACKEND          )
+DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit,     TextLabel, "fontSizeScale",             FLOAT,   FONT_SIZE_SCALE            )
 DALI_ANIMATABLE_PROPERTY_REGISTRATION_WITH_DEFAULT( Toolkit, TextLabel, "textColor",      Color::BLACK,     TEXT_COLOR     )
 DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit,    TextLabel, "textColorRed",   TEXT_COLOR_RED,   TEXT_COLOR, 0  )
 DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit,    TextLabel, "textColorGreen", TEXT_COLOR_GREEN, TEXT_COLOR, 1  )
@@ -466,6 +467,17 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
         impl.mTextUpdateNeeded = impl.mController->SetDefaultLineSize( lineSize ) || impl.mTextUpdateNeeded;
         break;
       }
+      case Toolkit::DevelTextLabel::Property::FONT_SIZE_SCALE:
+      {
+        const float scale = value.Get< float >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel %p FONT_SIZE_SCALE %f\n", impl.mController.Get(), scale );
+
+        if( !Equals( impl.mController->GetFontSizeScale(), scale ) )
+        {
+          impl.mController->SetFontSizeScale( scale );
+        }
+        break;
+      }
     }
 
     // Request relayout when text update is needed. It's necessary to call it
@@ -694,6 +706,11 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde
         value = impl.mController->GetDefaultLineSize();
         break;
       }
+      case Toolkit::DevelTextLabel::Property::FONT_SIZE_SCALE:
+      {
+        value = impl.mController->GetFontSizeScale();
+        break;
+      }
     }
   }
 
index eba2eef..9b68176 100644 (file)
@@ -90,7 +90,7 @@ LoadingTask::LoadingTask( uint32_t id, Devel::PixelBuffer pixelBuffer, Devel::Pi
 }
 
 void LoadingTask::Load()
-{;
+{
   if( animatedImageLoading )
   {
     pixelBuffer = animatedImageLoading.LoadFrame( frameIndex );
index b0aa82e..32bf7ab 100644 (file)
@@ -959,7 +959,7 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
 
       // Get the default font's description.
       TextAbstraction::FontDescription defaultFontDescription;
-      TextAbstraction::PointSize26Dot6 defaultPointSize = TextAbstraction::FontClient::DEFAULT_POINT_SIZE;
+      TextAbstraction::PointSize26Dot6 defaultPointSize = TextAbstraction::FontClient::DEFAULT_POINT_SIZE * mFontSizeScale;
 
       if( IsShowingPlaceholderText() && mEventData && ( NULL != mEventData->mPlaceholderFont ) )
       {
@@ -967,7 +967,7 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
         defaultFontDescription = mEventData->mPlaceholderFont->mFontDescription;
         if( mEventData->mPlaceholderFont->sizeDefined )
         {
-          defaultPointSize = mEventData->mPlaceholderFont->mDefaultPointSize * 64u;
+          defaultPointSize = mEventData->mPlaceholderFont->mDefaultPointSize * mFontSizeScale * 64u;
         }
       }
       else if( NULL != mFontDefaults )
@@ -981,7 +981,7 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
         }
         else
         {
-          defaultPointSize = mFontDefaults->mDefaultPointSize * 64u;
+          defaultPointSize = mFontDefaults->mDefaultPointSize * mFontSizeScale * 64u;
         }
       }
 
@@ -1332,11 +1332,11 @@ float Controller::Impl::GetDefaultFontLineHeight()
   if( NULL == mFontDefaults )
   {
     TextAbstraction::FontDescription fontDescription;
-    defaultFontId = mFontClient.GetFontId( fontDescription );
+    defaultFontId = mFontClient.GetFontId( fontDescription, TextAbstraction::FontClient::DEFAULT_POINT_SIZE * mFontSizeScale );
   }
   else
   {
-    defaultFontId = mFontDefaults->GetFontId( mFontClient );
+    defaultFontId = mFontDefaults->GetFontId( mFontClient, mFontDefaults->mDefaultPointSize * mFontSizeScale );
   }
 
   Text::FontMetrics fontMetrics;
index 61714e6..1c6702c 100755 (executable)
@@ -43,6 +43,7 @@ namespace Text
 const float DEFAULT_TEXTFIT_MIN = 10.f;
 const float DEFAULT_TEXTFIT_MAX = 100.f;
 const float DEFAULT_TEXTFIT_STEP = 1.f;
+const float DEFAULT_FONT_SIZE_SCALE = 1.f;
 
 //Forward declarations
 struct CursorInfo;
@@ -206,11 +207,11 @@ struct FontDefaults
     fontClient.GetDefaultPlatformFontDescription( mFontDescription );
   }
 
-  FontId GetFontId( TextAbstraction::FontClient& fontClient )
+  FontId GetFontId( TextAbstraction::FontClient& fontClient, float fontPointSize )
   {
     if( !mFontId )
     {
-      const PointSize26Dot6 pointSize = static_cast<PointSize26Dot6>( mDefaultPointSize * 64.f );
+      const PointSize26Dot6 pointSize = static_cast<PointSize26Dot6>( fontPointSize * 64.f );
       mFontId = fontClient.GetFontId( mFontDescription, pointSize );
     }
 
@@ -349,7 +350,8 @@ struct Controller::Impl
     mTextFitMinSize( DEFAULT_TEXTFIT_MIN ),
     mTextFitMaxSize( DEFAULT_TEXTFIT_MAX ),
     mTextFitStepSize( DEFAULT_TEXTFIT_STEP ),
-    mTextFitEnabled( false )
+    mTextFitEnabled( false ),
+    mFontSizeScale( DEFAULT_FONT_SIZE_SCALE )
   {
     mModel = Model::New();
 
@@ -828,6 +830,7 @@ public:
   float mTextFitMaxSize;                   ///< Maximum Font Size for text fit. Default 100
   float mTextFitStepSize;                  ///< Step Size for font intervalse. Default 1
   bool  mTextFitEnabled : 1;               ///< Whether the text's fit is enabled.
+  float mFontSizeScale;                    ///< Scale value for Font Size. Default 1.0
 
 private:
   friend ControllerImplEventHandler;
index 21bd604..3eb74a1 100644 (file)
@@ -397,7 +397,7 @@ void Controller::InputFontHandler::SetInputFontPointSize(Controller& controller,
                                                                               startOfSelectedText,
                                                                               lengthOfSelectedText );
 
-        fontDescriptionRun.size = static_cast<PointSize26Dot6>( size * 64.f );
+        fontDescriptionRun.size = static_cast<PointSize26Dot6>( size * controller.mImpl->mFontSizeScale * 64.f );
         fontDescriptionRun.sizeDefined = true;
 
         controller.mImpl->mTextUpdateInfo.mCharacterIndex = startOfSelectedText;
index aed8d32..d00330e 100644 (file)
@@ -989,6 +989,36 @@ FontSlant Controller::GetPlaceholderTextFontSlant() const
   return PlaceholderHandler::GetPlaceholderTextFontSlant(*this);
 }
 
+void Controller::SetFontSizeScale( float scale )
+{
+  mImpl->mFontSizeScale = scale;
+
+  if( mImpl->mEventData )
+  {
+    // Update the cursor position if it's in editing mode
+    if( EventData::IsEditingState( mImpl->mEventData->mState ) )
+    {
+      mImpl->mEventData->mDecoratorUpdated = true;
+      mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font size is updated.
+    }
+  }
+
+  // Clear the font-specific data
+  ClearFontData();
+
+  mImpl->RequestRelayout();
+}
+
+float Controller::GetFontSizeScale() const
+{
+  if( nullptr != mImpl->mFontDefaults )
+  {
+    return mImpl->mFontSizeScale;
+  }
+
+  return 1.f;
+}
+
 void Controller::SetDefaultFontSize( float fontSize, FontSizeType type )
 {
   if( NULL == mImpl->mFontDefaults )
@@ -2511,7 +2541,7 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ
 
       if( addFontSizeRun )
       {
-        fontDescriptionRun.size = static_cast<PointSize26Dot6>( mImpl->mEventData->mInputStyle.size * 64.f );
+        fontDescriptionRun.size = static_cast<PointSize26Dot6>( mImpl->mEventData->mInputStyle.size * mImpl->mFontSizeScale * 64.f );
         fontDescriptionRun.sizeDefined = true;
       }
 
index d627324..4e6f99b 100644 (file)
@@ -860,6 +860,20 @@ public: // Default style & Input style
   float GetDefaultFontSize( FontSizeType type ) const;
 
   /**
+   * @brief Set the font size scale.
+   *
+   * @param[in] scale The font size scale
+   */
+  void SetFontSizeScale( float scale );
+
+  /**
+   * @brief Get the font size scale.
+   *
+   * @return The font size scale.
+   */
+  float GetFontSizeScale() const;
+
+  /**
    * @brief Sets the Placeholder text font size.
    * @param[in] fontSize The placeholder text font size
    * @param[in] type The font size type is point size or pixel size
index fead0e6..93c0966 100644 (file)
@@ -270,8 +270,8 @@ void AnimatedVectorImageVisual::DoSetOnScene( Actor& actor )
 
   if( mImpl->mCustomShader )
   {
-    shader = Shader::New( mImpl->mCustomShader->mVertexShader.empty() ? mImageVisualShaderFactory.GetVertexShaderSource() : mImpl->mCustomShader->mVertexShader,
-                          mImpl->mCustomShader->mFragmentShader.empty() ? mImageVisualShaderFactory.GetFragmentShaderSource() : mImpl->mCustomShader->mFragmentShader,
+    shader = Shader::New( mImpl->mCustomShader->mVertexShader.empty() ? mImageVisualShaderFactory.GetVertexShaderSource().data() : mImpl->mCustomShader->mVertexShader,
+                          mImpl->mCustomShader->mFragmentShader.empty() ? mImageVisualShaderFactory.GetFragmentShaderSource().data() : mImpl->mCustomShader->mFragmentShader,
                           mImpl->mCustomShader->mHints );
 
     shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
index babfc94..71e2383 100644 (file)
@@ -47,102 +47,103 @@ DALI_ENUM_TO_STRING_WITH_SCOPE( DevelArcVisual::Cap, BUTT )
 DALI_ENUM_TO_STRING_WITH_SCOPE( DevelArcVisual::Cap, ROUND )
 DALI_ENUM_TO_STRING_TABLE_END( CAP )
 
-const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
-  attribute mediump vec2 aPosition;\n
-  uniform highp   mat4 uMvpMatrix;\n
-  uniform mediump vec3 uSize;\n
-  \n
-  varying mediump vec2 vPosition;\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
-
-  vec4 ComputeVertexPosition()\n
-  {\n
-    vec2 visualSize = mix(uSize.xy*size, size, offsetSizeMode.zw );\n
-    vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy);\n
-    vPosition = aPosition* visualSize;\n
-    return vec4( vPosition + anchorPoint*visualSize + (visualOffset + origin)*uSize.xy, 0.0, 1.0 );\n
-  }\n
-
-  void main()\n
-  {\n
-    gl_Position = uMvpMatrix * ComputeVertexPosition();\n
-  }\n
-);
-
-const char* FRAGMENT_SHADER_BUTT_CAP = DALI_COMPOSE_SHADER(
-  varying mediump vec2 vPosition;\n
-  uniform lowp vec4 uColor;\n
-  uniform lowp vec3 mixColor;\n
-  uniform mediump float thickness;\n
-  uniform mediump float radius;\n
-  uniform mediump float startAngle;\n
-  uniform mediump float sweepAngle;\n
-  \n
-  const mediump float M_PI_OVER_2 = 1.57079632679;\n
-  const mediump float M_PI = 3.14159265359;\n
-  const mediump float M_PI_2 = 6.28318530718;\n
-  \n
-  mediump float GetOpacity()\n
-  {\n
-      mediump float start = radians( mod( startAngle, 360.0 ) );\n
-      mediump float angle = mod( atan( vPosition.y, vPosition.x ) + M_PI_OVER_2 - start, M_PI_2 );\n
-      mediump float dist = length( vPosition );\n
-      if( angle <= radians( sweepAngle ) )\n
-      {\n
-        return smoothstep( -1.0, 1.0, thickness / 2.0 - ( abs( dist - radius ) ) );\n
-      }\n
-      mediump float end = radians( mod( startAngle + sweepAngle, 360.0 ) );\n
-      mediump vec2 q0 = vec2( dist * cos( start - M_PI_OVER_2 ), dist * sin( start - M_PI_OVER_2 ) );\n
-      mediump vec2 q1 = vec2( dist * cos( end - M_PI_OVER_2 ), dist * sin( end - M_PI_OVER_2 ) );\n
-      mediump float opacity = 1.0 - smoothstep( 0.0, 2.0, min( length( vPosition - q0 ), length( vPosition - q1 ) ) );\n
-      opacity *= step( 0.0, thickness / 2.0 - abs( dist - radius ) );\n
-      return opacity;\n
-  }\n
-  void main()\n
-  {\n
-    gl_FragColor = vec4( mixColor, 1.0 ) * uColor;\n
-    gl_FragColor.a *= GetOpacity();\n
-  }\n
-);
-
-const char* FRAGMENT_SHADER_ROUND_CAP = DALI_COMPOSE_SHADER(
-  varying mediump vec2 vPosition;\n
-  uniform lowp vec4 uColor;\n
-  uniform lowp vec3 mixColor;\n
-  uniform mediump float thickness;\n
-  uniform mediump float radius;\n
-  uniform mediump float startAngle;\n
-  uniform mediump float sweepAngle;\n
-  \n
-  const mediump float M_PI_OVER_2 = 1.57079632679;\n
-  const mediump float M_PI_2 = 6.28318530718;\n
-  \n
-  mediump float GetOpacity()\n
-  {\n
-      mediump float start = radians( mod( startAngle, 360.0 ) );\n
-      mediump float angle = mod( atan( vPosition.y, vPosition.x ) + M_PI_OVER_2 - start, M_PI_2 );\n
-      mediump float dist = length( vPosition );\n
-      if( angle <= radians( sweepAngle ) )\n
-      {\n
-        return smoothstep( -1.0, 1.0, thickness / 2.0 - ( abs( dist - radius ) ) );\n
-      }\n
-      mediump float end = radians( mod( startAngle + sweepAngle, 360.0 ) );\n
-      mediump vec2 q0 = vec2( radius * cos( start - M_PI_OVER_2 ), radius * sin( start - M_PI_OVER_2 ) );\n
-      mediump vec2 q1 = vec2( radius * cos( end - M_PI_OVER_2 ), radius * sin( end - M_PI_OVER_2 ) );\n
-      return smoothstep( -1.0, 1.0, thickness / 2.0 - min( length( vPosition - q0 ), length( vPosition - q1 ) ) );\n
-  }\n
-  void main()\n
-  {\n
-    gl_FragColor = vec4( mixColor, 1.0 ) * uColor;\n
-    gl_FragColor.a *= GetOpacity();\n
-  }\n
-);
+const char* VERTEX_SHADER =
+  "INPUT mediump vec2 aPosition;\n"
+  "OUTPUT mediump vec2 vPosition;\n"
+
+  "uniform highp mat4 uMvpMatrix;\n"
+  "uniform highp vec3 uSize;\n"
+
+  "//Visual size and offset\n"
+  "uniform mediump vec2 offset;\n"
+  "uniform highp vec2 size;\n"
+  "uniform mediump vec4 offsetSizeMode;\n"
+  "uniform mediump vec2 origin;\n"
+  "uniform mediump vec2 anchorPoint;\n"
+
+  "vec4 ComputeVertexPosition()\n"
+  "{\n"
+  "  vec2 visualSize = mix(uSize.xy*size, size, offsetSizeMode.zw );\n"
+  "  vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy);\n"
+  "  vPosition = aPosition* visualSize;\n"
+  "  return vec4( vPosition + anchorPoint*visualSize + (visualOffset + origin)*uSize.xy, 0.0, 1.0 );\n"
+  "}\n"
+
+  "void main()\n"
+  "{\n"
+  "  gl_Position = uMvpMatrix * ComputeVertexPosition();\n"
+  "}\n";
+
+const char* FRAGMENT_SHADER_BUTT_CAP =
+  "INPUT mediump vec2 vPosition;\n"
+
+  "uniform lowp vec4 uColor;\n"
+  "uniform lowp vec3 mixColor;\n"
+  "uniform mediump float thickness;\n"
+  "uniform mediump float radius;\n"
+  "uniform mediump float startAngle;\n"
+  "uniform mediump float sweepAngle;\n"
+
+  "const mediump float M_PI_OVER_2 = 1.57079632679;\n"
+  "const mediump float M_PI = 3.14159265359;\n"
+  "const mediump float M_PI_2 = 6.28318530718;\n"
+
+  "mediump float GetOpacity()\n"
+  "{\n"
+  "  mediump float start = radians( mod( startAngle, 360.0 ) );\n"
+  "  mediump float angle = mod( atan( vPosition.y, vPosition.x ) + M_PI_OVER_2 - start, M_PI_2 );\n"
+  "  mediump float dist = length( vPosition );\n"
+  "  if( angle <= radians( sweepAngle ) )\n"
+  "  {\n"
+  "    return smoothstep( -1.0, 1.0, thickness / 2.0 - ( abs( dist - radius ) ) );\n"
+  "  }\n"
+  "  mediump float end = radians( mod( startAngle + sweepAngle, 360.0 ) );\n"
+  "  mediump vec2 q0 = vec2( dist * cos( start - M_PI_OVER_2 ), dist * sin( start - M_PI_OVER_2 ) );\n"
+  "  mediump vec2 q1 = vec2( dist * cos( end - M_PI_OVER_2 ), dist * sin( end - M_PI_OVER_2 ) );\n"
+  "  mediump float opacity = 1.0 - smoothstep( 0.0, 2.0, min( length( vPosition - q0 ), length( vPosition - q1 ) ) );\n"
+  "  opacity *= step( 0.0, thickness / 2.0 - abs( dist - radius ) );\n"
+  "  return opacity;\n"
+  "}\n"
+
+  "void main()\n"
+  "{\n"
+  "  OUT_COLOR = vec4( mixColor, 1.0 ) * uColor;\n"
+  "  OUT_COLOR.a *= GetOpacity();\n"
+  "}\n";
+
+const char* FRAGMENT_SHADER_ROUND_CAP =
+  "INPUT mediump vec2 vPosition;\n"
+
+  "uniform lowp vec4 uColor;\n"
+  "uniform lowp vec3 mixColor;\n"
+  "uniform mediump float thickness;\n"
+  "uniform mediump float radius;\n"
+  "uniform mediump float startAngle;\n"
+  "uniform mediump float sweepAngle;\n"
+
+  "const mediump float M_PI_OVER_2 = 1.57079632679;\n"
+  "const mediump float M_PI_2 = 6.28318530718;\n"
+
+  "mediump float GetOpacity()\n"
+  "{\n"
+  "  mediump float start = radians( mod( startAngle, 360.0 ) );\n"
+  "  mediump float angle = mod( atan( vPosition.y, vPosition.x ) + M_PI_OVER_2 - start, M_PI_2 );\n"
+  "  mediump float dist = length( vPosition );\n"
+  "  if( angle <= radians( sweepAngle ) )\n"
+  "  {\n"
+  "    return smoothstep( -1.0, 1.0, thickness / 2.0 - ( abs( dist - radius ) ) );\n"
+  "  }\n"
+  "  mediump float end = radians( mod( startAngle + sweepAngle, 360.0 ) );\n"
+  "  mediump vec2 q0 = vec2( radius * cos( start - M_PI_OVER_2 ), radius * sin( start - M_PI_OVER_2 ) );\n"
+  "  mediump vec2 q1 = vec2( radius * cos( end - M_PI_OVER_2 ), radius * sin( end - M_PI_OVER_2 ) );\n"
+  "  return smoothstep( -1.0, 1.0, thickness / 2.0 - min( length( vPosition - q0 ), length( vPosition - q1 ) ) );\n"
+  "}\n"
+
+  "void main()\n"
+  "{\n"
+  "  OUT_COLOR = vec4( mixColor, 1.0 ) * uColor;\n"
+  "  OUT_COLOR.a *= GetOpacity();\n"
+  "}\n";
 
 }
 
@@ -296,7 +297,7 @@ void ArcVisual::InitializeRenderer()
     shader = mFactoryCache.GetShader( VisualFactoryCache::ARC_BUTT_CAP_SHADER );
     if( !shader )
     {
-      shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_BUTT_CAP );
+      shader = Shader::New( Dali::Shader::GetVertexShaderPrefix() + VERTEX_SHADER, Dali::Shader::GetFragmentShaderPrefix() + FRAGMENT_SHADER_BUTT_CAP );
       mFactoryCache.SaveShader( VisualFactoryCache::ARC_BUTT_CAP_SHADER, shader );
     }
   }
@@ -305,7 +306,7 @@ void ArcVisual::InitializeRenderer()
     shader = mFactoryCache.GetShader( VisualFactoryCache::ARC_ROUND_CAP_SHADER );
     if( !shader )
     {
-      shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_ROUND_CAP );
+      shader = Shader::New( Dali::Shader::GetVertexShaderPrefix() + VERTEX_SHADER, Dali::Shader::GetFragmentShaderPrefix() + FRAGMENT_SHADER_ROUND_CAP );
       mFactoryCache.SaveShader( VisualFactoryCache::ARC_ROUND_CAP_SHADER, shader );
     }
   }
index 03412bf..ddd2e52 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
@@ -20,6 +20,7 @@
 
 // EXTERNAL INCLUDES
 #include <dali/integration-api/debug.h>
+#include <dali/devel-api/rendering/renderer-devel.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/visuals/border-visual-properties.h>
@@ -44,76 +45,73 @@ const char * const POSITION_ATTRIBUTE_NAME("aPosition");
 const char * const DRIFT_ATTRIBUTE_NAME("aDrift");
 const char * const INDEX_NAME("indices");
 
-
-const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
-  attribute mediump vec2 aPosition;\n
-  attribute mediump vec2 aDrift;\n
-  uniform highp   mat4 uMvpMatrix;\n
-  uniform highp   vec3 uSize;\n
-  uniform mediump float borderSize;\n
-  \n
-
-  //Visual size and offset
-  uniform mediump vec2 offset;\n
-  uniform highp   vec2 size;\n
-  uniform mediump vec4 offsetSizeMode;\n
-  uniform mediump vec2 origin;\n
-  uniform mediump vec2 anchorPoint;\n
-
-  vec2 ComputeVertexPosition()\n
-  {\n
-    vec2 visualSize = mix(uSize.xy*size, size, offsetSizeMode.zw );\n
-    vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy);\n
-    return (aPosition + anchorPoint)*visualSize + (visualOffset + origin)*uSize.xy;\n
-  }\n
-
-  void main()\n
-  {\n
-    vec2 position = ComputeVertexPosition() + aDrift*borderSize;\n
-    gl_Position = uMvpMatrix * vec4(position, 0.0, 1.0);\n
-  }\n
-);
-
-const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
-  uniform lowp vec4 uColor;\n
-  uniform lowp vec4 borderColor;\n
-  uniform lowp vec3 mixColor;\n
-  \n
-  void main()\n
-  {\n
-    gl_FragColor = vec4(mixColor, 1.0)*borderColor*uColor;\n
-  }\n
-);
-
-const char* VERTEX_SHADER_ANTI_ALIASING = DALI_COMPOSE_SHADER(
-  attribute mediump vec2 aPosition;\n
-  attribute mediump vec2 aDrift;\n
-  uniform highp   mat4 uMvpMatrix;\n
-  uniform highp   vec3 uSize;\n
-  uniform mediump float borderSize;\n
-  varying mediump float vAlpha;\n
-  \n
-  void main()\n
-  {\n
-    vec2 position = aPosition*(uSize.xy+vec2(0.75)) + aDrift*(borderSize+1.5);\n
-    gl_Position = uMvpMatrix * vec4(position, 0.0, 1.0);\n
-    vAlpha = min( abs(aDrift.x), abs(aDrift.y) )*(borderSize+1.5);
-  }\n
-);
-
-const char* FRAGMENT_SHADER_ANTI_ALIASING = DALI_COMPOSE_SHADER(
-  uniform lowp vec4 uColor;\n
-  uniform lowp vec4 borderColor;\n
-  uniform lowp vec3 mixColor;\n
-  uniform mediump float borderSize;\n
-  varying mediump float vAlpha;\n
-  \n
-  void main()\n
-  {\n
-    gl_FragColor = vec4(mixColor, 1.0)*borderColor*uColor;\n
-    gl_FragColor.a *= smoothstep(0.0, 1.5, vAlpha)*smoothstep( borderSize+1.5, borderSize, vAlpha );\n
-  }\n
-);
+const char* VERTEX_SHADER =
+  "INPUT mediump vec2 aPosition;\n"
+  "INPUT mediump vec2 aDrift;\n"
+
+  "uniform highp mat4 uMvpMatrix;\n"
+  "uniform highp vec3 uSize;\n"
+  "uniform mediump float borderSize;\n"
+
+  "//Visual size and offset\n"
+  "uniform mediump vec2 offset;\n"
+  "uniform highp vec2 size;\n"
+  "uniform mediump vec4 offsetSizeMode;\n"
+  "uniform mediump vec2 origin;\n"
+  "uniform mediump vec2 anchorPoint;\n"
+
+  "vec2 ComputeVertexPosition()\n"
+  "{\n"
+  "  vec2 visualSize = mix(uSize.xy*size, size, offsetSizeMode.zw );\n"
+  "  vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy);\n"
+  "  return (aPosition + anchorPoint)*visualSize + (visualOffset + origin)*uSize.xy;\n"
+  "}\n"
+
+  "void main()\n"
+  "{\n"
+  "  vec2 position = ComputeVertexPosition() + aDrift*borderSize;\n"
+  "  gl_Position = uMvpMatrix * vec4(position, 0.0, 1.0);\n"
+  "}\n";
+
+const char* FRAGMENT_SHADER =
+  "uniform lowp vec4 uColor;\n"
+  "uniform lowp vec4 borderColor;\n"
+  "uniform lowp vec3 mixColor;\n"
+
+  "void main()\n"
+  "{\n"
+  "  OUT_COLOR = vec4(mixColor, 1.0) * borderColor * uColor;\n"
+  "}\n";
+
+const char* VERTEX_SHADER_ANTI_ALIASING =
+  "INPUT mediump vec2 aPosition;\n"
+  "INPUT mediump vec2 aDrift;\n"
+  "OUTPUT mediump float vAlpha;\n"
+
+  "uniform highp mat4 uMvpMatrix;\n"
+  "uniform highp vec3 uSize;\n"
+  "uniform mediump float borderSize;\n"
+
+  "void main()\n"
+  "{\n"
+  "  vec2 position = aPosition*(uSize.xy+vec2(0.75)) + aDrift*(borderSize+1.5);\n"
+  "  gl_Position = uMvpMatrix * vec4(position, 0.0, 1.0);\n"
+  "  vAlpha = min( abs(aDrift.x), abs(aDrift.y) )*(borderSize+1.5);"
+  "}\n";
+
+const char* FRAGMENT_SHADER_ANTI_ALIASING =
+  "INPUT mediump float vAlpha;\n"
+
+  "uniform lowp vec4 uColor;\n"
+  "uniform lowp vec4 borderColor;\n"
+  "uniform lowp vec3 mixColor;\n"
+  "uniform mediump float borderSize;\n"
+
+  "void main()\n"
+  "{\n"
+  "  OUT_COLOR = vec4(mixColor, 1.0) * borderColor * uColor;\n"
+  "  OUT_COLOR.a *= smoothstep(0.0, 1.5, vAlpha) * smoothstep( borderSize + 1.5, borderSize, vAlpha );\n"
+  "}\n";
 }
 
 BorderVisualPtr BorderVisual::New( VisualFactoryCache& factoryCache, const Property::Map& properties )
@@ -201,7 +199,7 @@ void BorderVisual::DoSetOnScene( Actor& actor )
   InitializeRenderer();
 
   mBorderColorIndex = mImpl->mRenderer.RegisterProperty( Toolkit::BorderVisual::Property::COLOR, COLOR_NAME, mBorderColor );
-  if( mBorderColor.a < 1.f || mAntiAliasing)
+  if( ( mBorderColor.a < 1.f || mAntiAliasing ) || IsAdvancedBlendEquationApplied() )
   {
     mImpl->mRenderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON );
   }
@@ -259,7 +257,7 @@ Shader BorderVisual::GetBorderShader()
     shader = mFactoryCache.GetShader( VisualFactoryCache::BORDER_SHADER_ANTI_ALIASING );
     if( !shader )
     {
-      shader = Shader::New( VERTEX_SHADER_ANTI_ALIASING, FRAGMENT_SHADER_ANTI_ALIASING );
+      shader = Shader::New( Dali::Shader::GetVertexShaderPrefix() + VERTEX_SHADER_ANTI_ALIASING, Dali::Shader::GetFragmentShaderPrefix() + FRAGMENT_SHADER_ANTI_ALIASING );
       mFactoryCache.SaveShader( VisualFactoryCache::BORDER_SHADER_ANTI_ALIASING, shader );
     }
   }
@@ -268,7 +266,7 @@ Shader BorderVisual::GetBorderShader()
     shader = mFactoryCache.GetShader( VisualFactoryCache::BORDER_SHADER );
     if( !shader )
     {
-      shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
+      shader = Shader::New( Dali::Shader::GetVertexShaderPrefix() + VERTEX_SHADER, Dali::Shader::GetFragmentShaderPrefix() + FRAGMENT_SHADER );
       mFactoryCache.SaveShader( VisualFactoryCache::BORDER_SHADER, shader );
     }
   }
index 4fae268..793b8b2 100644 (file)
@@ -20,6 +20,7 @@
 
 // EXTERNAL INCLUDES
 #include <dali/integration-api/debug.h>
+#include <dali/devel-api/rendering/renderer-devel.h>
 
 //INTERNAL INCLUDES
 #include <dali-toolkit/public-api/visuals/color-visual-properties.h>
@@ -43,140 +44,139 @@ namespace Internal
 namespace
 {
 
-const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
-  attribute mediump vec2 aPosition;\n
-  uniform highp   mat4 uMvpMatrix;\n
-  uniform highp   vec3 uSize;\n
-  \n
-
-  //Visual size and offset
-  uniform mediump vec2 offset;\n
-  uniform highp   vec2 size;\n
-  uniform mediump vec4 offsetSizeMode;\n
-  uniform mediump vec2 origin;\n
-  uniform mediump vec2 anchorPoint;\n
-  uniform mediump vec2 extraSize;\n
-
-  vec4 ComputeVertexPosition()\n
-  {\n
-    vec2 visualSize = mix(uSize.xy*size, size, offsetSizeMode.zw ) + extraSize;\n
-    vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy);\n
-    return vec4( (aPosition + anchorPoint)*visualSize + (visualOffset + origin)*uSize.xy, 0.0, 1.0 );\n
-  }\n
-
-  void main()\n
-  {\n
-    gl_Position = uMvpMatrix * ComputeVertexPosition();\n
-  }\n
-);
-
-const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
-  uniform lowp vec4 uColor;\n
-  uniform lowp vec3 mixColor;\n
-  \n
-  void main()\n
-  {\n
-    gl_FragColor = vec4(mixColor, 1.0)*uColor;\n
-  }\n
-);
-
-const char* VERTEX_SHADER_ROUNDED_CORNER = DALI_COMPOSE_SHADER(
-  attribute mediump vec2 aPosition;\n
-  uniform highp   mat4 uMvpMatrix;\n
-  uniform highp   vec3 uSize;\n
-  varying mediump vec2 vPosition;\n
-  varying mediump vec2 vRectSize;\n
-  varying mediump float vCornerRadius;\n
-  \n
-  //Visual size and offset
-  uniform mediump vec2 offset;\n
-  uniform highp   vec2 size;\n
-  uniform mediump vec2 extraSize;\n
-  uniform mediump vec4 offsetSizeMode;\n
-  uniform mediump vec2 origin;\n
-  uniform mediump vec2 anchorPoint;\n
-  uniform mediump float cornerRadius;\n
-  uniform mediump float cornerRadiusPolicy;\n
-  \n
-  vec4 ComputeVertexPosition()\n
-  {\n
-    vec2 visualSize = mix(uSize.xy*size, size, offsetSizeMode.zw ) + extraSize;\n
-    vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy);\n
-    mediump float minSize = min( visualSize.x, visualSize.y );\n
-    vCornerRadius = mix( cornerRadius * minSize, cornerRadius, cornerRadiusPolicy);\n
-    vCornerRadius = min( vCornerRadius, minSize * 0.5 );\n
-    vRectSize = visualSize / 2.0 - vCornerRadius;\n
-    vPosition = aPosition* visualSize;\n
-    return vec4( vPosition + anchorPoint*visualSize + (visualOffset + origin)*uSize.xy, 0.0, 1.0 );\n
-  }\n
-  \n
-  void main()\n
-  {\n
-    gl_Position = uMvpMatrix * ComputeVertexPosition();\n
-  }\n
-);
+const char* VERTEX_SHADER =
+  "INPUT mediump vec2 aPosition;\n"
+
+  "uniform highp mat4 uMvpMatrix;\n"
+  "uniform highp vec3 uSize;\n"
+
+  "//Visual size and offset\n"
+  "uniform mediump vec2 offset;\n"
+  "uniform highp vec2 size;\n"
+  "uniform mediump vec4 offsetSizeMode;\n"
+  "uniform mediump vec2 origin;\n"
+  "uniform mediump vec2 anchorPoint;\n"
+  "uniform mediump vec2 extraSize;\n"
+
+  "vec4 ComputeVertexPosition()\n"
+  "{\n"
+  "  vec2 visualSize = mix(uSize.xy*size, size, offsetSizeMode.zw ) + extraSize;\n"
+  "  vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy);\n"
+  "  return vec4( (aPosition + anchorPoint)*visualSize + (visualOffset + origin)*uSize.xy, 0.0, 1.0 );\n"
+  "}\n"
+
+  "void main()\n"
+  "{\n"
+  "  gl_Position = uMvpMatrix * ComputeVertexPosition();\n"
+  "}\n";
+
+
+const char* FRAGMENT_SHADER =
+  "uniform lowp vec4 uColor;\n"
+  "uniform lowp vec3 mixColor;\n"
+
+  "void main()\n"
+  "{\n"
+  "  OUT_COLOR = vec4(mixColor, 1.0) * uColor;\n"
+  "}\n";
+
+const char* VERTEX_SHADER_ROUNDED_CORNER =
+  "INPUT mediump vec2 aPosition;\n"
+  "OUTPUT mediump vec2 vPosition;\n"
+  "OUTPUT mediump vec2 vRectSize;\n"
+  "OUTPUT mediump float vCornerRadius;\n"
+
+  "uniform highp mat4 uMvpMatrix;\n"
+  "uniform highp vec3 uSize;\n"
+
+  "//Visual size and offset\n"
+  "uniform mediump vec2 offset;\n"
+  "uniform highp vec2 size;\n"
+  "uniform mediump vec2 extraSize;\n"
+  "uniform mediump vec4 offsetSizeMode;\n"
+  "uniform mediump vec2 origin;\n"
+  "uniform mediump vec2 anchorPoint;\n"
+  "uniform mediump float cornerRadius;\n"
+  "uniform mediump float cornerRadiusPolicy;\n"
+
+  "vec4 ComputeVertexPosition()\n"
+  "{\n"
+  "  vec2 visualSize = mix(uSize.xy*size, size, offsetSizeMode.zw ) + extraSize;\n"
+  "  vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy);\n"
+  "  mediump float minSize = min( visualSize.x, visualSize.y );\n"
+  "  vCornerRadius = mix( cornerRadius * minSize, cornerRadius, cornerRadiusPolicy);\n"
+  "  vCornerRadius = min( vCornerRadius, minSize * 0.5 );\n"
+  "  vRectSize = visualSize / 2.0 - vCornerRadius;\n"
+  "  vPosition = aPosition* visualSize;\n"
+  "  return vec4( vPosition + anchorPoint*visualSize + (visualOffset + origin)*uSize.xy, 0.0, 1.0 );\n"
+  "}\n"
+
+  "void main()\n"
+  "{\n"
+  "  gl_Position = uMvpMatrix * ComputeVertexPosition();\n"
+  "}\n";
 
 //float distance = length( max( abs( position - center ), size ) - size ) - radius;
-const char* FRAGMENT_SHADER_ROUNDED_CORNER = DALI_COMPOSE_SHADER(
-  varying mediump vec2 vPosition;\n
-  varying mediump vec2 vRectSize;\n
-  varying mediump float vCornerRadius;\n
-  uniform lowp vec4 uColor;\n
-  uniform lowp vec3 mixColor;\n
-  \n
-  void main()\n
-  {\n
-      mediump float dist = length( max( abs( vPosition ), vRectSize ) - vRectSize ) - vCornerRadius;\n
-      gl_FragColor = uColor * vec4( mixColor, 1.0 );\n
-      gl_FragColor.a *= 1.0 - smoothstep( -1.0, 1.0, dist );\n
-  }\n
-);
-
-const char* VERTEX_SHADER_BLUR_EDGE = DALI_COMPOSE_SHADER(
-  attribute mediump vec2 aPosition;\n
-  uniform highp   mat4 uMvpMatrix;\n
-  uniform highp vec3 uSize;\n
-  varying mediump vec2 vPosition;\n
-  varying mediump vec2 vRectSize;\n
-  \n
-  //Visual size and offset
-  uniform mediump vec2 offset;\n
-  uniform highp vec2 size;\n
-  uniform mediump vec2 extraSize;\n
-  uniform mediump vec4 offsetSizeMode;\n
-  uniform mediump vec2 origin;\n
-  uniform mediump vec2 anchorPoint;\n
-  uniform mediump float blurRadius;\n
-  \n
-  vec4 ComputeVertexPosition()\n
-  {\n
-    vec2 visualSize = mix(uSize.xy*size, size, offsetSizeMode.zw ) + extraSize + blurRadius * 2.0;\n
-    vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy);\n
-    vRectSize = visualSize / 2.0;\n
-    vPosition = aPosition* visualSize;\n
-    return vec4( vPosition + anchorPoint*visualSize + (visualOffset + origin)*uSize.xy, 0.0, 1.0 );\n
-  }\n
-  \n
-  void main()\n
-  {\n
-    gl_Position = uMvpMatrix * ComputeVertexPosition();\n
-  }\n
-);
-
-const char* FRAGMENT_SHADER_BLUR_EDGE = DALI_COMPOSE_SHADER(
-  varying mediump vec2 vPosition;\n
-  varying mediump vec2 vRectSize;\n
-  uniform lowp vec4 uColor;\n
-  uniform lowp vec3 mixColor;\n
-  uniform mediump float blurRadius;\n
-  \n
-  void main()\n
-  {\n
-      mediump vec2 blur = 1.0 - smoothstep( vRectSize - blurRadius * 2.0, vRectSize, abs( vPosition ) );\n
-      gl_FragColor = uColor * vec4( mixColor, 1.0 );\n
-      gl_FragColor.a *= blur.x * blur.y;\n
-  }\n
-);
+const char* FRAGMENT_SHADER_ROUNDED_CORNER =
+  "INPUT mediump vec2 vPosition;\n"
+  "INPUT mediump vec2 vRectSize;\n"
+  "INPUT mediump float vCornerRadius;\n"
+
+  "uniform lowp vec4 uColor;\n"
+  "uniform lowp vec3 mixColor;\n"
+
+  "void main()\n"
+  "{\n"
+  "  mediump float dist = length( max( abs( vPosition ), vRectSize ) - vRectSize ) - vCornerRadius;\n"
+  "  OUT_COLOR = vec4(mixColor, 1.0) * uColor;\n"
+  "  OUT_COLOR.a *= 1.0 - smoothstep( -1.0, 1.0, dist );\n"
+  "}\n";
+
+const char* VERTEX_SHADER_BLUR_EDGE =
+  "INPUT mediump vec2 aPosition;\n"
+  "OUTPUT mediump vec2 vPosition;\n"
+  "OUTPUT mediump vec2 vRectSize;\n"
+
+  "uniform highp   mat4 uMvpMatrix;\n"
+  "uniform highp vec3 uSize;\n"
+
+  "//Visual size and offset\n"
+  "uniform mediump vec2 offset;\n"
+  "uniform highp vec2 size;\n"
+  "uniform mediump vec2 extraSize;\n"
+  "uniform mediump vec4 offsetSizeMode;\n"
+  "uniform mediump vec2 origin;\n"
+  "uniform mediump vec2 anchorPoint;\n"
+  "uniform mediump float blurRadius;\n"
+
+  "vec4 ComputeVertexPosition()\n"
+  "{\n"
+  "  vec2 visualSize = mix(uSize.xy*size, size, offsetSizeMode.zw ) + extraSize + blurRadius * 2.0;\n"
+  "  vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy);\n"
+  "  vRectSize = visualSize / 2.0;\n"
+  "  vPosition = aPosition* visualSize;\n"
+  "  return vec4( vPosition + anchorPoint*visualSize + (visualOffset + origin)*uSize.xy, 0.0, 1.0 );\n"
+  "}\n"
+
+  "void main()\n"
+  "{\n"
+  "  gl_Position = uMvpMatrix * ComputeVertexPosition();\n"
+  "}\n";
+
+const char* FRAGMENT_SHADER_BLUR_EDGE =
+  "INPUT mediump vec2 vPosition;\n"
+  "INPUT mediump vec2 vRectSize;\n"
+
+  "uniform lowp vec4 uColor;\n"
+  "uniform lowp vec3 mixColor;\n"
+  "uniform mediump float blurRadius;\n"
+
+  "void main()\n"
+  "{\n"
+  "  mediump vec2 blur = 1.0 - smoothstep( vRectSize - blurRadius * 2.0, vRectSize, abs( vPosition ) );\n"
+  "  OUT_COLOR = vec4(mixColor, 1.0) * uColor;\n"
+  "  OUT_COLOR.a *= blur.x * blur.y;\n"
+  "}\n";
 
 }
 
@@ -309,7 +309,7 @@ void ColorVisual::InitializeRenderer()
     shader = mFactoryCache.GetShader( VisualFactoryCache::COLOR_SHADER_BLUR_EDGE );
     if( !shader )
     {
-      shader = Shader::New( VERTEX_SHADER_BLUR_EDGE, FRAGMENT_SHADER_BLUR_EDGE );
+      shader = Shader::New( Dali::Shader::GetVertexShaderPrefix() + VERTEX_SHADER_BLUR_EDGE, Dali::Shader::GetFragmentShaderPrefix() + FRAGMENT_SHADER_BLUR_EDGE );
       mFactoryCache.SaveShader( VisualFactoryCache::COLOR_SHADER_BLUR_EDGE, shader );
     }
   }
@@ -318,7 +318,7 @@ void ColorVisual::InitializeRenderer()
     shader = mFactoryCache.GetShader( VisualFactoryCache::COLOR_SHADER );
     if( !shader )
     {
-      shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
+      shader = Shader::New( Dali::Shader::GetVertexShaderPrefix() + VERTEX_SHADER, Dali::Shader::GetFragmentShaderPrefix() + FRAGMENT_SHADER );
       mFactoryCache.SaveShader( VisualFactoryCache::COLOR_SHADER, shader );
     }
   }
@@ -327,7 +327,7 @@ void ColorVisual::InitializeRenderer()
     shader = mFactoryCache.GetShader( VisualFactoryCache::COLOR_SHADER_ROUNDED_CORNER );
     if( !shader )
     {
-      shader = Shader::New( VERTEX_SHADER_ROUNDED_CORNER, FRAGMENT_SHADER_ROUNDED_CORNER );
+      shader = Shader::New( Dali::Shader::GetVertexShaderPrefix() + VERTEX_SHADER_ROUNDED_CORNER, Dali::Shader::GetFragmentShaderPrefix() + FRAGMENT_SHADER_ROUNDED_CORNER );
       mFactoryCache.SaveShader( VisualFactoryCache::COLOR_SHADER_ROUNDED_CORNER, shader );
     }
   }
@@ -341,7 +341,7 @@ void ColorVisual::InitializeRenderer()
 
   mImpl->mRenderer.RegisterProperty( BLUR_RADIUS_NAME, mBlurRadius );
 
-  if( mImpl->mMixColor.a < 1.f || !EqualsZero( mBlurRadius ) )
+  if( mImpl->mMixColor.a < 1.f || !EqualsZero( mBlurRadius ) || IsAdvancedBlendEquationApplied() )
   {
     mImpl->mRenderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON );
   }
index 462a6c0..7d39a77 100644 (file)
@@ -25,6 +25,7 @@
 #include <dali/public-api/object/property-array.h>
 #include <dali/devel-api/scripting/enum-helper.h>
 #include <dali/devel-api/scripting/scripting.h>
+#include <dali/devel-api/rendering/renderer-devel.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/visuals/gradient-visual-properties.h>
@@ -458,8 +459,8 @@ void GradientVisual::InitializeRenderer()
   mImpl->mRenderer = Renderer::New( geometry, shader );
   mImpl->mRenderer.SetTextures( textureSet );
 
-  // If opaque then no need to have blending
-  if( mIsOpaque )
+  // If opaque and then no need to have blending
+  if( mIsOpaque && !IsAdvancedBlendEquationApplied() )
   {
     mImpl->mRenderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::OFF );
   }
index 45d0e3f..5bc09ce 100644 (file)
@@ -21,6 +21,7 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
+#include <dali/integration-api/debug.h>
 
 namespace Dali
 {
@@ -36,150 +37,160 @@ namespace
 
 const Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f);
 
-const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
-  attribute mediump vec2 aPosition;\n
-  uniform highp   mat4 uMvpMatrix;\n
-  uniform highp   vec3 uSize;\n
-  uniform mediump vec4 pixelArea;
-  varying mediump vec2 vTexCoord;\n
-  \n
-  //Visual size and offset
-  uniform mediump vec2 offset;\n
-  uniform highp   vec2 size;\n
-  uniform mediump vec4 offsetSizeMode;\n
-  uniform mediump vec2 origin;\n
-  uniform mediump vec2 anchorPoint;\n
-  uniform mediump vec2 extraSize;\n
-\n
-  vec4 ComputeVertexPosition()\n
-  {\n
-    vec2 visualSize = mix(uSize.xy*size, size, offsetSizeMode.zw ) + extraSize;\n
-    vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy);\n
-    return vec4( (aPosition + anchorPoint)*visualSize + (visualOffset + origin)*uSize.xy, 0.0, 1.0 );\n
-  }\n
-\n
-  void main()\n
-  {\n
-    gl_Position = uMvpMatrix * ComputeVertexPosition();\n
-    vTexCoord = pixelArea.xy+pixelArea.zw*(aPosition + vec2(0.5) );\n
-  }\n
-);
-
-const char* FRAGMENT_SHADER_NO_ATLAS = DALI_COMPOSE_SHADER(
-  varying mediump vec2 vTexCoord;\n
-  uniform sampler2D sTexture;\n
-  uniform lowp vec4 uColor;\n
-  uniform lowp vec3 mixColor;\n
-  uniform lowp float preMultipliedAlpha;\n
-  \n
-  void main()\n
-  {\n
-      gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor * vec4( mixColor, 1.0 );\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 preMultipliedAlpha;\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, 1.0 );\n
-     }\n
-);
-
-const char* FRAGMENT_SHADER_ATLAS_VARIOUS_WRAP = DALI_COMPOSE_SHADER(
-    varying mediump vec2 vTexCoord;\n
-    uniform sampler2D sTexture;\n
-    uniform mediump vec4 uAtlasRect;\n
-    // WrapMode -- 0: CLAMP; 1: REPEAT; 2: REFLECT;
-    uniform lowp vec2 wrapMode;\n
-    uniform lowp vec4 uColor;\n
-    uniform lowp vec3 mixColor;\n
-    uniform lowp float preMultipliedAlpha;\n
-    \n
-    mediump float wrapCoordinate( mediump vec2 range, mediump float coordinate, lowp float wrap )\n
-    {\n
-      mediump float coord;\n
-      if( wrap > 1.5 )\n // REFLECT
-        coord = 1.0-abs(fract(coordinate*0.5)*2.0 - 1.0);\n
-      else \n// warp == 0 or 1
-        coord = mix(coordinate, fract( coordinate ), wrap);\n
-      return clamp( mix(range.x, range.y, coord), range.x, range.y );
-    }\n
-    \n
-    void main()\n
-    {\n
-        mediump vec2 texCoord = vec2( wrapCoordinate( uAtlasRect.xz, vTexCoord.x, wrapMode.x ),
-                                      wrapCoordinate( uAtlasRect.yw, vTexCoord.y, wrapMode.y ) );\n
-        gl_FragColor = texture2D( sTexture, texCoord ) * uColor * vec4( mixColor, 1.0 );\n
-    }\n
-);
-
-const char* VERTEX_SHADER_ROUNDED_CORNER = DALI_COMPOSE_SHADER(
-  attribute mediump vec2 aPosition;\n
-  uniform highp   mat4 uMvpMatrix;\n
-  uniform mediump vec3 uSize;\n
-  uniform mediump vec4 pixelArea;
-  varying mediump vec2 vTexCoord;\n
-  varying mediump vec2 vPosition;\n
-  varying mediump vec2 vRectSize;\n
-  varying mediump float vCornerRadius;\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
-  uniform mediump float cornerRadius;\n
-  uniform mediump float cornerRadiusPolicy;\n
-  uniform mediump vec2 extraSize;\n
-  \n
-  vec4 ComputeVertexPosition()\n
-  {\n
-    vec2 visualSize = mix(uSize.xy*size, size, offsetSizeMode.zw ) + extraSize;\n
-    vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy);\n
-    mediump float minSize = min( visualSize.x, visualSize.y );\n
-    vCornerRadius = mix( cornerRadius * minSize, cornerRadius, cornerRadiusPolicy);\n
-    vCornerRadius = min( vCornerRadius, minSize * 0.5 );\n
-    vRectSize = visualSize * 0.5 - vCornerRadius;\n
-    vPosition = aPosition* visualSize;\n
-    return vec4( vPosition + anchorPoint*visualSize + (visualOffset + origin)*uSize.xy, 0.0, 1.0 );\n
-  }\n
-\n
-  void main()\n
-  {\n
-    gl_Position = uMvpMatrix * ComputeVertexPosition();\n
-    vTexCoord = pixelArea.xy+pixelArea.zw*(aPosition + vec2(0.5) );\n
-  }\n
-);
+const char* VERTEX_SHADER =
+  "INPUT mediump vec2 aPosition;\n"
+  "OUTPUT mediump vec2 vTexCoord;\n"
+
+  "uniform highp mat4 uMvpMatrix;\n"
+  "uniform highp vec3 uSize;\n"
+  "uniform mediump vec4 pixelArea;"
+  "//Visual size and offset\n"
+
+  "uniform mediump vec2 offset;\n"
+  "uniform highp vec2 size;\n"
+  "uniform mediump vec4 offsetSizeMode;\n"
+  "uniform mediump vec2 origin;\n"
+  "uniform mediump vec2 anchorPoint;\n"
+  "uniform mediump vec2 extraSize;\n"
+
+  "vec4 ComputeVertexPosition()\n"
+  "{\n"
+  "  vec2 visualSize = mix(uSize.xy*size, size, offsetSizeMode.zw ) + extraSize;\n"
+  "  vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy);\n"
+  "  return vec4( (aPosition + anchorPoint)*visualSize + (visualOffset + origin)*uSize.xy, 0.0, 1.0 );\n"
+  "}\n"
+  "\n"
+  "void main()\n"
+  "{\n"
+  "  gl_Position = uMvpMatrix * ComputeVertexPosition();\n"
+  "  vTexCoord = pixelArea.xy+pixelArea.zw*(aPosition + vec2(0.5) );\n"
+  "}\n";
+
+const char* FRAGMENT_SHADER_NO_ATLAS =
+  "INPUT mediump vec2 vTexCoord;\n"
+
+  "uniform sampler2D sTexture;\n"
+  "uniform lowp vec4 uColor;\n"
+  "uniform lowp vec3 mixColor;\n"
+  "uniform lowp float preMultipliedAlpha;\n"
+
+  "void main()\n"
+  "{\n"
+  "  OUT_COLOR = TEXTURE( sTexture, vTexCoord ) * uColor * vec4( mixColor, 1.0 );\n"
+  "}\n";
+
+
+const char* FRAGMENT_SHADER_ATLAS_CLAMP =
+  "INPUT 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 preMultipliedAlpha;\n"
+
+  "void main()\n"
+  "{\n"
+  "  mediump vec2 texCoord = clamp( mix( uAtlasRect.xy, uAtlasRect.zw, vTexCoord ), uAtlasRect.xy, uAtlasRect.zw );\n"
+  "  OUT_COLOR = TEXTURE( sTexture, texCoord ) * uColor * vec4( mixColor, 1.0 );\n"
+  "}\n";
+
+
+const char* FRAGMENT_SHADER_ATLAS_VARIOUS_WRAP =
+  "INPUT mediump vec2 vTexCoord;\n"
+
+  "uniform sampler2D sTexture;\n"
+  "uniform mediump vec4 uAtlasRect;\n"
+  "// WrapMode -- 0: CLAMP; 1: REPEAT; 2: REFLECT;"
+  "uniform lowp vec2 wrapMode;\n"
+  "uniform lowp vec4 uColor;\n"
+  "uniform lowp vec3 mixColor;\n"
+  "uniform lowp float preMultipliedAlpha;\n"
+  "mediump float wrapCoordinate( mediump vec2 range, mediump float coordinate, lowp float wrap )\n"
+
+  "{\n"
+  "  mediump float coord;\n"
+  "  if( wrap > 1.5 )\n // REFLECT"
+  "    coord = 1.0-abs(fract(coordinate*0.5)*2.0 - 1.0);\n"
+  "  else \n// warp == 0 or 1"
+  "    coord = mix(coordinate, fract( coordinate ), wrap);\n"
+  "  return clamp( mix(range.x, range.y, coord), range.x, range.y );"
+  "}\n"
+
+  "void main()\n"
+  "{\n"
+  "  mediump vec2 texCoord = vec2( wrapCoordinate( uAtlasRect.xz, vTexCoord.x, wrapMode.x ),"
+  "                                wrapCoordinate( uAtlasRect.yw, vTexCoord.y, wrapMode.y ) );\n"
+  "  OUT_COLOR = TEXTURE( sTexture, texCoord ) * uColor * vec4( mixColor, 1.0 );\n"
+  "}\n";
+
+const char* VERTEX_SHADER_ROUNDED_CORNER =
+  "INPUT mediump vec2 aPosition;\n"
+  "OUTPUT mediump vec2 vTexCoord;\n"
+  "OUTPUT mediump vec2 vPosition;\n"
+  "OUTPUT mediump vec2 vRectSize;\n"
+  "OUTPUT mediump float vCornerRadius;\n"
+
+  "uniform highp mat4 uMvpMatrix;\n"
+  "uniform highp vec3 uSize;\n"
+  "uniform mediump vec4 pixelArea;"
+
+  "//Visual size and offset\n"
+  "uniform mediump vec2 offset;\n"
+  "uniform highp vec2 size;\n"
+  "uniform mediump vec4 offsetSizeMode;\n"
+  "uniform mediump vec2 origin;\n"
+  "uniform mediump vec2 anchorPoint;\n"
+  "uniform mediump float cornerRadius;\n"
+  "uniform mediump float cornerRadiusPolicy;\n"
+  "uniform mediump vec2 extraSize;\n"
+
+  "vec4 ComputeVertexPosition()\n"
+  "{\n"
+  "  vec2 visualSize = mix(uSize.xy*size, size, offsetSizeMode.zw ) + extraSize;\n"
+  "  vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy);\n"
+  "  mediump float minSize = min( visualSize.x, visualSize.y );\n"
+  "  vCornerRadius = mix( cornerRadius * minSize, cornerRadius, cornerRadiusPolicy);\n"
+  "  vCornerRadius = min( vCornerRadius, minSize * 0.5 );\n"
+  "  vRectSize = visualSize * 0.5 - vCornerRadius;\n"
+  "  vPosition = aPosition* visualSize;\n"
+  "  return vec4( vPosition + anchorPoint*visualSize + (visualOffset + origin)*uSize.xy, 0.0, 1.0 );\n"
+  "}\n"
+
+  "void main()\n"
+  "{\n"
+  "  gl_Position = uMvpMatrix * ComputeVertexPosition();\n"
+  "  vTexCoord = pixelArea.xy+pixelArea.zw*(aPosition + vec2(0.5) );\n"
+  "}\n";
+
 
 //float distance = length( max( abs( position - center ), size ) - size ) - radius;
-const char* FRAGMENT_SHADER_ROUNDED_CORNER = DALI_COMPOSE_SHADER(
-  varying mediump vec2 vTexCoord;\n
-  varying mediump vec2 vPosition;\n
-  varying mediump vec2 vRectSize;\n
-  varying mediump float vCornerRadius;\n
-  uniform sampler2D sTexture;\n
-  uniform lowp vec4 uColor;\n
-  uniform lowp vec3 mixColor;\n
-  uniform lowp float preMultipliedAlpha;\n
-  \n
-  void main()\n
-  {\n
-      mediump float dist = length( max( abs( vPosition ), vRectSize ) - vRectSize ) - vCornerRadius;\n
-      mediump float opacity = 1.0 - smoothstep( -1.0, 1.0, dist );\n
-      gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor * vec4( mixColor, 1.0 );\n
-      gl_FragColor.a *= opacity;\n
-      gl_FragColor.rgb *= mix( 1.0, opacity, preMultipliedAlpha );\n
-  }\n
-);
+const char* FRAGMENT_SHADER_ROUNDED_CORNER =
+  "INPUT mediump vec2 vTexCoord;\n"
+  "INPUT mediump vec2 vPosition;\n"
+  "INPUT mediump vec2 vRectSize;\n"
+  "INPUT mediump float vCornerRadius;\n"
+
+  "uniform sampler2D sTexture;\n"
+  "uniform lowp vec4 uColor;\n"
+  "uniform lowp vec3 mixColor;\n"
+  "uniform lowp float preMultipliedAlpha;\n"
+
+  "void main()\n"
+  "{\n"
+  "  mediump float dist = length( max( abs( vPosition ), vRectSize ) - vRectSize ) - vCornerRadius;\n"
+  "  mediump float opacity = 1.0 - smoothstep( -1.0, 1.0, dist );\n"
+
+  "  OUT_COLOR = TEXTURE( sTexture, vTexCoord ) * uColor * vec4( mixColor, 1.0 );\n"
+  "  OUT_COLOR.a *= opacity;\n"
+  "  OUT_COLOR.rgb *= mix( 1.0, opacity, preMultipliedAlpha );\n"
+  "}\n";
+
+// global string variable to caching complate vertex shader
+static std::string gVertexShader;
+
+// global string variable to caching complate fragment shader (no atlas)
+static std::string gFragmentShaderNoAtlas;
 
 } // unnamed namespace
 
@@ -201,7 +212,7 @@ Shader ImageVisualShaderFactory::GetShader( VisualFactoryCache& factoryCache, bo
       shader = factoryCache.GetShader( VisualFactoryCache::IMAGE_SHADER_ATLAS_DEFAULT_WRAP );
       if( !shader )
       {
-        shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_ATLAS_CLAMP );
+        shader = Shader::New( Dali::Shader::GetVertexShaderPrefix() + VERTEX_SHADER, Dali::Shader::GetFragmentShaderPrefix() + FRAGMENT_SHADER_ATLAS_CLAMP );
         shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
         factoryCache.SaveShader( VisualFactoryCache::IMAGE_SHADER_ATLAS_DEFAULT_WRAP, shader );
       }
@@ -211,7 +222,7 @@ Shader ImageVisualShaderFactory::GetShader( VisualFactoryCache& factoryCache, bo
       shader = factoryCache.GetShader( VisualFactoryCache::IMAGE_SHADER_ATLAS_CUSTOM_WRAP );
       if( !shader )
       {
-        shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_ATLAS_VARIOUS_WRAP );
+        shader = Shader::New( Dali::Shader::GetVertexShaderPrefix() + VERTEX_SHADER, Dali::Shader::GetFragmentShaderPrefix() + FRAGMENT_SHADER_ATLAS_VARIOUS_WRAP );
         shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
         factoryCache.SaveShader( VisualFactoryCache::IMAGE_SHADER_ATLAS_CUSTOM_WRAP, shader );
       }
@@ -224,7 +235,7 @@ Shader ImageVisualShaderFactory::GetShader( VisualFactoryCache& factoryCache, bo
       shader = factoryCache.GetShader( VisualFactoryCache::IMAGE_SHADER_ROUNDED_CORNER );
       if( !shader )
       {
-        shader = Shader::New( VERTEX_SHADER_ROUNDED_CORNER, FRAGMENT_SHADER_ROUNDED_CORNER );
+        shader = Shader::New( Dali::Shader::GetVertexShaderPrefix() + VERTEX_SHADER_ROUNDED_CORNER, Dali::Shader::GetFragmentShaderPrefix() + FRAGMENT_SHADER_ROUNDED_CORNER );
         shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
         factoryCache.SaveShader( VisualFactoryCache::IMAGE_SHADER_ROUNDED_CORNER, shader );
       }
@@ -234,7 +245,7 @@ Shader ImageVisualShaderFactory::GetShader( VisualFactoryCache& factoryCache, bo
       shader = factoryCache.GetShader( VisualFactoryCache::IMAGE_SHADER );
       if( !shader )
       {
-        shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_NO_ATLAS );
+        shader = Shader::New( Dali::Shader::GetVertexShaderPrefix() + VERTEX_SHADER, Dali::Shader::GetFragmentShaderPrefix() + FRAGMENT_SHADER_NO_ATLAS );
         shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
         factoryCache.SaveShader( VisualFactoryCache::IMAGE_SHADER, shader );
       }
@@ -244,14 +255,23 @@ Shader ImageVisualShaderFactory::GetShader( VisualFactoryCache& factoryCache, bo
   return shader;
 }
 
-const char* ImageVisualShaderFactory::GetVertexShaderSource()
+std::string_view ImageVisualShaderFactory::GetVertexShaderSource()
 {
-  return VERTEX_SHADER;
+  if(gVertexShader.empty())
+  {
+    gVertexShader = Dali::Shader::GetVertexShaderPrefix() + VERTEX_SHADER;
+  }
+
+  return gVertexShader;
 }
 
-const char* ImageVisualShaderFactory::GetFragmentShaderSource()
+std::string_view ImageVisualShaderFactory::GetFragmentShaderSource()
 {
-  return FRAGMENT_SHADER_NO_ATLAS;
+  if(gFragmentShaderNoAtlas.empty())
+  {
+    gFragmentShaderNoAtlas = Dali::Shader::GetFragmentShaderPrefix() + FRAGMENT_SHADER_NO_ATLAS;
+  }
+  return gFragmentShaderNoAtlas;
 }
 
 } // namespace Internal
index c5344d3..6d38fbd 100644 (file)
@@ -21,6 +21,7 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
+#include <string_view>
 
 namespace Dali
 {
@@ -63,13 +64,13 @@ public:
    * Request the default vertex shader source.
    * @return The default vertex shader source.
    */
-  const char* GetVertexShaderSource();
+  std::string_view GetVertexShaderSource();
 
   /**
    * Request the default fragment shader source.
    * @return The default fragment shader source.
    */
-  const char* GetFragmentShaderSource();
+  std::string_view GetFragmentShaderSource();
 
 protected:
 
index b0324ed..ec130e2 100644 (file)
@@ -543,7 +543,7 @@ void ImageVisual::CreateRenderer( TextureSet& textureSet )
   }
   else
   {
-    vertexShader = mImageVisualShaderFactory.GetVertexShaderSource();
+    vertexShader = mImageVisualShaderFactory.GetVertexShaderSource().data();
   }
 
   std::string fragmentShader;
@@ -553,7 +553,7 @@ void ImageVisual::CreateRenderer( TextureSet& textureSet )
   }
   else
   {
-    fragmentShader = mImageVisualShaderFactory.GetFragmentShaderSource();
+    fragmentShader = mImageVisualShaderFactory.GetFragmentShaderSource().data();
   }
 
   // If the texture is native, we may need to change prefix and sampler in
index 32ff4cf..09d8de2 100644 (file)
@@ -145,8 +145,8 @@ void SvgVisual::DoSetOnScene( Actor& actor )
   }
   else
   {
-    shader = Shader::New( mImpl->mCustomShader->mVertexShader.empty() ? mImageVisualShaderFactory.GetVertexShaderSource() : mImpl->mCustomShader->mVertexShader,
-                          mImpl->mCustomShader->mFragmentShader.empty() ? mImageVisualShaderFactory.GetFragmentShaderSource() : mImpl->mCustomShader->mFragmentShader,
+    shader = Shader::New( mImpl->mCustomShader->mVertexShader.empty() ? mImageVisualShaderFactory.GetVertexShaderSource().data() : mImpl->mCustomShader->mVertexShader,
+                          mImpl->mCustomShader->mFragmentShader.empty() ? mImageVisualShaderFactory.GetFragmentShaderSource().data() : mImpl->mCustomShader->mFragmentShader,
                           mImpl->mCustomShader->mHints );
 
     shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
index 64bbb5b..5e0b506 100644 (file)
@@ -819,6 +819,8 @@ void TextureManager::QueueLoadTexture( TextureInfo& textureInfo, TextureUploadOb
 {
   auto textureId = textureInfo.textureId;
   mLoadQueue.PushBack( LoadQueueElement( textureId, observer) );
+
+  observer->DestructionSignal().Connect( this, &TextureManager::ObserverDestroyed );
 }
 
 void TextureManager::LoadTexture( TextureInfo& textureInfo, TextureUploadObserver* observer )
@@ -853,6 +855,11 @@ void TextureManager::ProcessQueuedTextures()
 {
   for( auto&& element : mLoadQueue )
   {
+    if( !element.mObserver )
+    {
+      continue;
+    }
+
     int cacheIndex = GetCacheIndexFromId( element.mTextureId );
     if( cacheIndex != INVALID_CACHE_INDEX )
     {
@@ -1312,6 +1319,15 @@ void TextureManager::ObserverDestroyed( TextureUploadObserver* observer )
       }
     }
   }
+
+  // Remove element from the LoadQueue
+  for( auto&& element : mLoadQueue )
+  {
+    if( element.mObserver == observer )
+    {
+      element.mObserver = nullptr;
+    }
+  }
 }
 
 
index 885bc72..748bcec 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
@@ -413,6 +413,11 @@ bool Visual::Base::IsPreMultipliedAlphaEnabled() const
   return mImpl->mFlags & Impl::IS_PREMULTIPLIED_ALPHA;
 }
 
+bool Visual::Base::IsAdvancedBlendEquationApplied() const
+{
+  return IsPreMultipliedAlphaEnabled() && DevelRenderer::IsAdvancedBlendEquationApplied( mImpl->mRenderer );
+}
+
 void Visual::Base::DoSetOffScene( Actor& actor )
 {
   actor.RemoveRenderer( mImpl->mRenderer );
@@ -446,7 +451,7 @@ void Visual::Base::RegisterMixColor()
       Vector3(mImpl->mMixColor) );
   }
 
-  if( mImpl->mMixColor.a < 1.f )
+  if( mImpl->mMixColor.a < 1.f || IsAdvancedBlendEquationApplied() )
   {
     mImpl->mRenderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON );
   }
@@ -469,7 +474,7 @@ void Visual::Base::SetMixColor( const Vector4& color )
   {
     mImpl->mRenderer.SetProperty( mImpl->mMixColorIndex, Vector3(color) );
     mImpl->mRenderer.SetProperty( DevelRenderer::Property::OPACITY, color.a );
-    if( color.a < 1.f )
+    if( color.a < 1.f || IsAdvancedBlendEquationApplied() )
     {
       mImpl->mRenderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON );
     }
@@ -770,7 +775,8 @@ void Visual::Base::SetupBlendMode( Animation& transition, bool isInitialOpaque,
 {
   // Ensure the blend mode is turned on if we are animating opacity, and
   // turned off after the animation ends if the final value is opaque
-  if( ! isInitialOpaque || mImpl->mMixColor.a < 1.0f )
+  if( ( ! isInitialOpaque || mImpl->mMixColor.a < 1.0f ) ||
+      ( mImpl->mRenderer && IsAdvancedBlendEquationApplied() ) )
   {
     if( mImpl->mRenderer )
     {
@@ -795,8 +801,16 @@ void Visual::Base::OnMixColorFinished( Animation& animation )
   if( mImpl->mRenderer )
   {
     DALI_LOG_INFO( gVisualBaseLogFilter, Debug::General, "Visual::Base::OnMixColorFinished()\n");
-    mImpl->mRenderer.SetProperty( Renderer::Property::BLEND_MODE,
-                                  ( mImpl->mMixColor.a < 1.0 ) ? BlendMode::ON : BlendMode::AUTO );
+
+    if( mImpl->mMixColor.a >= 1.f &&
+        !IsAdvancedBlendEquationApplied() )
+    {
+      mImpl->mRenderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::AUTO );
+    }
+    else
+    {
+      mImpl->mRenderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON );
+    }
   }
   delete mImpl->mBlendSlotDelegate;
   mImpl->mBlendSlotDelegate = NULL;
index d9ff2dd..8fa2e5e 100644 (file)
@@ -170,6 +170,13 @@ public:
   bool IsPreMultipliedAlphaEnabled() const;
 
   /**
+   * @brief Query whether advanced blend equation is applied.
+   *
+   * @return True is advanced blend equation is applied, false otherwise.
+   */
+  bool IsAdvancedBlendEquationApplied() const;
+
+  /**
    * @brief Sets properties of custom shader
    * @param[in] propertyMap Property map containing the custom shader data
    */
index 2367539..f0756cd 100644 (file)
@@ -29,7 +29,7 @@ namespace Toolkit
 {
 const unsigned int TOOLKIT_MAJOR_VERSION = 2;
 const unsigned int TOOLKIT_MINOR_VERSION = 0;
-const unsigned int TOOLKIT_MICRO_VERSION = 0;
+const unsigned int TOOLKIT_MICRO_VERSION = 1;
 const char* const  TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index aae6b64..6e6bc45 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali2-toolkit
 Summary:    Dali 3D engine Toolkit
-Version:    2.0.0
+Version:    2.0.1
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT