Merge branch 'devel/master' into tizen_4.0 47/147047/1
authorHeeyong Song <heeyong.song@samsung.com>
Fri, 1 Sep 2017 00:48:32 +0000 (09:48 +0900)
committerHeeyong Song <heeyong.song@samsung.com>
Fri, 1 Sep 2017 00:48:36 +0000 (09:48 +0900)
Change-Id: I13039d30879b1a01b6fc0a39294c4cc9a1e64c32

26 files changed:
adaptors/common/adaptor-impl.cpp
adaptors/common/object-profiler.cpp
adaptors/common/object-profiler.h
adaptors/common/singleton-service-impl.cpp
adaptors/public-api/dali-adaptor-version.cpp
adaptors/tizen/accessibility-adaptor-impl-tizen.cpp
adaptors/wearable/watch-application-impl.cpp [changed mode: 0644->0755]
automated-tests/execute.sh
automated-tests/packaging/core-dali-adaptor-tests.spec
automated-tests/packaging/core-dali-platform-abstraction-tests.spec
automated-tests/scripts/tcheadgen.sh
automated-tests/src/dali-adaptor-internal/tct-dali-adaptor-internal-core.cpp
automated-tests/src/dali-adaptor/tct-dali-adaptor-core.cpp
automated-tests/src/dali-platform-abstraction/tct-dali-platform-abstraction-core.cpp
build/tizen/adaptor/Makefile.am
build/tizen/adaptor/configure.ac
packaging/dali-adaptor.spec
platform-abstractions/tizen/image-loaders/loader-png.cpp [changed mode: 0644->0755]
text/dali/devel-api/text-abstraction/font-client.cpp
text/dali/devel-api/text-abstraction/font-client.h
text/dali/internal/text-abstraction/font-client-helper.cpp
text/dali/internal/text-abstraction/font-client-helper.h
text/dali/internal/text-abstraction/font-client-impl.cpp
text/dali/internal/text-abstraction/font-client-impl.h
text/dali/internal/text-abstraction/font-client-plugin-impl.cpp
text/dali/internal/text-abstraction/font-client-plugin-impl.h

index 7261e4e..08fe0e0 100644 (file)
@@ -68,7 +68,7 @@ namespace Adaptor
 
 namespace
 {
-__thread Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
+thread_local Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
 } // unnamed namespace
 
 Dali::Adaptor* Adaptor::New( Any nativeWindow, RenderSurface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
index 7d86bf0..47c771c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -57,21 +57,18 @@ ObjectProfiler::~ObjectProfiler()
 
 void ObjectProfiler::DisplayInstanceCounts()
 {
-  InstanceCountMapIterator iter = mInstanceCountMap.begin();
-  InstanceCountMapIterator end = mInstanceCountMap.end();
-
-  for( ; iter != end; iter++ )
+  for( auto&& element : mInstanceCountContainer )
   {
-    int memorySize = GetMemorySize(iter->first, iter->second);
+    int memorySize = GetMemorySize( element.first, element.second );
     if( memorySize > 0 )
     {
       LogMessage( Debug::DebugInfo, "%-30s: % 4d  Memory MemorySize: ~% 6.1f kB\n",
-                  iter->first.c_str(), iter->second, memorySize / 1024.0f );
+                  element.first.c_str(), element.second, memorySize / 1024.0f );
     }
     else
     {
       LogMessage( Debug::DebugInfo, "%-30s: % 4d\n",
-                  iter->first.c_str(), iter->second );
+                  element.first.c_str(), element.second );
     }
   }
   LogMessage(Debug::DebugInfo, "\n");
@@ -94,15 +91,19 @@ void ObjectProfiler::OnObjectCreated(BaseHandle handle)
 
   mInstanceTypes.push_back(InstanceTypePair(&handle.GetBaseObject(), theType));
 
-  InstanceCountMapIterator iter = mInstanceCountMap.find(theType);
-  if( iter == mInstanceCountMap.end() )
+  bool found = false;
+  for( auto&& element : mInstanceCountContainer )
   {
-    InstanceCountPair instanceCount(theType, 1);
-    mInstanceCountMap.insert(instanceCount);
+    if( element.first == theType )
+    {
+      element.second++;
+      found = true;
+    }
   }
-  else
+  if( !found )
   {
-    iter->second++;
+    InstanceCountPair instanceCount( theType, 1 );
+    mInstanceCountContainer.emplace_back( instanceCount );
   }
 }
 
@@ -110,22 +111,25 @@ void ObjectProfiler::OnObjectDestroyed(const Dali::RefObject* object)
 {
   const BaseObject* baseObject = static_cast<const BaseObject*>(object);
 
-  InstanceTypes::iterator end = mInstanceTypes.end();
-  for( InstanceTypes::iterator iter = mInstanceTypes.begin(); iter != end; iter++)
+  const auto end = mInstanceTypes.end();
+  for( auto iter = mInstanceTypes.begin(); iter != end; ++iter )
   {
     if( iter->first == baseObject )
     {
-      const std::string& theType = iter->second;
+      const auto& theType = iter->second;
       if( !theType.empty() )
       {
-        InstanceCountMapIterator countIter = mInstanceCountMap.find(theType);
-        if( countIter != mInstanceCountMap.end() )
+        auto&& countIter = std::find_if( mInstanceCountContainer.begin(),
+                                         mInstanceCountContainer.end(),
+                                         [theType] ( const InstanceCountPair& instance )
+                                                   { return instance.first == theType; } );
+        if( countIter != mInstanceCountContainer.end() )
         {
-          countIter->second--;
+          (*countIter).second--;
         }
       }
       mInstanceTypes.erase( iter );
-      break;
+      return;
     }
   }
 }
index eca7972..13a78c0 100644 (file)
@@ -2,7 +2,7 @@
 #define __DALI_ADAPTOR_OBJECT_PROFILER_H__
 
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -19,9 +19,9 @@
  */
 
 // EXTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
 #include <dali/public-api/object/object-registry.h>
 #include <dali/public-api/object/type-registry.h>
-#include <dali/devel-api/common/map-wrapper.h>
 #include <dali/public-api/signals/connection-tracker.h>
 
 // INTERNAL INCLUDES
@@ -81,16 +81,14 @@ private:
   int GetMemorySize(const std::string& name, int count);
 
 private:
-  typedef std::map<std::string, int> InstanceCountMap;
-  typedef std::pair<const std::string, int> InstanceCountPair;
-  typedef InstanceCountMap::iterator InstanceCountMapIterator;
-  typedef std::pair<BaseObject*, std::string> InstanceTypePair;
-  typedef std::vector<InstanceTypePair> InstanceTypes;
+
+  using InstanceCountPair = std::pair< const std::string, int >;
+  using InstanceTypePair = std::pair< BaseObject*, std::string >;
 
   Dali::ObjectRegistry    mObjectRegistry;
   Dali::Timer             mTimer;
-  InstanceCountMap        mInstanceCountMap;
-  InstanceTypes           mInstanceTypes;
+  std::vector< InstanceCountPair > mInstanceCountContainer;
+  std::vector< InstanceTypePair >  mInstanceTypes;
 };
 
 } // Adaptor
index d975d94..5ee6180 100644 (file)
@@ -48,10 +48,9 @@ namespace Internal
 namespace Adaptor
 {
 
-// @todo Start using pthread_key_create if we want to avoid leaking the SingletonService on shutdown
 namespace
 {
-__thread SingletonService * gSingletonService = 0;
+thread_local SingletonService * gSingletonService = 0;
 } // unnamed namespace
 
 Dali::SingletonService SingletonService::New()
index 30abfe8..7668053 100644 (file)
@@ -28,7 +28,7 @@ namespace Dali
 
 const unsigned int ADAPTOR_MAJOR_VERSION = 1;
 const unsigned int ADAPTOR_MINOR_VERSION = 2;
-const unsigned int ADAPTOR_MICRO_VERSION = 52;
+const unsigned int ADAPTOR_MICRO_VERSION = 54;
 const char * const ADAPTOR_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index 65ba859..dd0f61f 100644 (file)
@@ -42,14 +42,15 @@ namespace
 
 const char * DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_DBUS_TTS = "db/setting/accessibility/atspi";
 
+// Disabled Accessibility temporarily in Tizen platform
 bool GetEnabledVConf()
 {
   int isEnabled = 0;
-  vconf_get_bool( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_DBUS_TTS, &isEnabled );
+  //vconf_get_bool( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_DBUS_TTS, &isEnabled );
 
   if( isEnabled == 0 )
   {
-    vconf_get_bool( VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, &isEnabled );
+    //vconf_get_bool( VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, &isEnabled );
   }
 
   return static_cast<bool>(isEnabled);
old mode 100644 (file)
new mode 100755 (executable)
index 2f47a33..7bad7fe
@@ -50,12 +50,22 @@ void WatchApplication::OnTimeTick(WatchTime& time)
 {
   Dali::WatchApplication watch(this);
   mTickSignal.Emit( watch, time );
+
+  // A watch application will queue messages to update the UI in the signal emitted above
+  // Process these immediately to avoid a blinking issue where the old time is briefly visible
+  CoreEventInterface& eventInterface = Internal::Adaptor::Adaptor::GetImplementation( GetAdaptor() );
+  eventInterface.ProcessCoreEvents();
 }
 
 void WatchApplication::OnAmbientTick(WatchTime& time)
 {
   Dali::WatchApplication watch(this);
   mAmbientTickSignal.Emit( watch, time );
+
+  // A watch application will queue messages to update the UI in the signal emitted above
+  // Process these immediately to avoid a blinking issue where the old time is briefly visible
+  CoreEventInterface& eventInterface = Internal::Adaptor::Adaptor::GetImplementation( GetAdaptor() );
+  eventInterface.ProcessCoreEvents();
 }
 
 void WatchApplication::OnAmbientChanged(bool ambient)
index bc51cfb..902ba11 100755 (executable)
@@ -1,6 +1,6 @@
 #!/bin/bash
 
-TEMP=`getopt -o dhsSm --long debug,help,serial,tct,modules -n 'execute.sh' -- "$@"`
+TEMP=`getopt -o dhsSmf --long debug,help,failnorerun,serial,tct,modules -n 'execute.sh' -- "$@"`
 
 if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
 
@@ -11,6 +11,7 @@ function usage
 {
     echo -e "Usage: execute.sh [-d][-s|-S|-r] [module|testcase]"
     echo -e "       execute.sh\t\tExecute test cases from all modules in parallel"
+    echo -e "       execute.sh -f \tExecute test cases from all modules in parallel without rerunning failed test cases"
     echo -e "       execute.sh -d <testcase>\tDebug testcase"
     echo -e "       execute.sh [module]\tExecute test cases from the given module in parallel"
     echo -e "       execute.sh -s [module]\t\tExecute test cases in serial using Testkit-Lite"
@@ -23,11 +24,13 @@ opt_tct=0
 opt_serial=""
 opt_modules=0
 opt_debug=0
+opt_noFailedRerun="";
 while true ; do
     case "$1" in
         -h|--help)     usage ;;
         -d|--debug)    opt_debug=1 ; shift ;;
         -s|--tct)      opt_tct=1 ; shift ;;
+        -f|--nofailedrerun) opt_noFailedRerun="-f" ; shift ;;
         -S|--serial)   opt_serial="-s" ; shift ;;
         -m|--modules)  opt_modules=1 ; shift ;;
         --) shift; break;;
@@ -116,7 +119,7 @@ else
         do
             echo -e "$ASCII_BOLD"
             echo -e "Executing $mod$ASCII_RESET"
-            build/src/$mod/tct-$mod-core -r $opt_serial
+            build/src/$mod/tct-$mod-core $opt_serial $opt_noFailedRerun
         done
         summary_end
 
@@ -126,7 +129,7 @@ else
         summary_start
         module=$1
         shift;
-        build/src/$module/tct-$module-core -r $opt_serial $*
+        build/src/$module/tct-$module-core $opt_serial $opt_noFailedRerun $*
         summary_end
 
     else
index ab92054..ba56a0f 100644 (file)
@@ -35,8 +35,6 @@ make %{?jobs:-j%jobs}
 rm -rf %{buildroot}
 cd automated-tests
 %make_install
-mkdir -p %{buildroot}/opt/usr/share/license
-cp %{_builddir}/%{name}-%{version}/LICENSE %{buildroot}/opt/usr/share/license/%{name}
 mkdir -p %{buildroot}/tmp/
 cp %{_builddir}/%{name}-%{version}/automated-tests/scripts/add_all_smack_rule.sh %{buildroot}/tmp/
 cp %{_builddir}/%{name}-%{version}/automated-tests/scripts/all_smack.rule %{buildroot}/tmp/
@@ -48,6 +46,6 @@ cp %{_builddir}/%{name}-%{version}/automated-tests/scripts/all_smack.rule %{buil
 
 %files
 /opt/usr/bin/*
-/opt/usr/share/license/%{name}
 /tmp/add_all_smack_rule.sh
 /tmp/all_smack.rule
+%license LICENSE
\ No newline at end of file
index 93dd567..497d5b1 100644 (file)
@@ -35,8 +35,6 @@ make %{?jobs:-j%jobs}
 rm -rf %{buildroot}
 cd automated-tests
 %make_install
-mkdir -p %{buildroot}/opt/usr/share/license
-cp %{_builddir}/%{name}-%{version}/LICENSE %{buildroot}/opt/usr/share/license/%{name}
 mkdir -p %{buildroot}/tmp/
 cp %{_builddir}/%{name}-%{version}/automated-tests/scripts/add_all_smack_rule.sh %{buildroot}/tmp/
 cp %{_builddir}/%{name}-%{version}/automated-tests/scripts/all_smack.rule %{buildroot}/tmp/
@@ -48,6 +46,6 @@ cp %{_builddir}/%{name}-%{version}/automated-tests/scripts/all_smack.rule %{buil
 
 %files
 /opt/usr/bin/*
-/opt/usr/share/license/%{name}
 /tmp/add_all_smack_rule.sh
 /tmp/all_smack.rule
+%license LICENSE
index c7b7700..dfd378a 100755 (executable)
@@ -6,7 +6,7 @@ if [[ -z $1 ]]; then
 fi
 
 FILE="$PWD/$1"
-TFILE="/tmp/retr.csv"
+TFILE="/tmp/retr.csv$$"
 HEADER_NAME=$(echo $1 | tr '[:lower:]' '[:upper:]' | sed -e 's/-/_/g' -e 's/\./_/')
 SCRIPT_DIR="$(cd "$(dirname $0)" && pwd)"
 
@@ -69,3 +69,5 @@ print "};"
 print ""
 print "#endif // __" HEADER_NAME "__"
 }' $TFILE > $FILE
+unlink $TFILE
+
index 37f40d0..1dfb194 100644 (file)
@@ -8,7 +8,7 @@ int main(int argc, char * const argv[])
 {
   int result = TestHarness::EXIT_STATUS_BAD_ARGUMENT;
 
-  const char* optString = "rs";
+  const char* optString = "sf";
   bool optRerunFailed(true);
   bool optRunSerially(false);
 
@@ -18,8 +18,8 @@ int main(int argc, char * const argv[])
     nextOpt = getopt( argc, argv, optString );
     switch(nextOpt)
     {
-      case 'r':
-        optRerunFailed = true;
+      case 'f':
+        optRerunFailed = false;
         break;
       case 's':
         optRunSerially = true;
index dfaa9a4..86e70c9 100644 (file)
@@ -8,7 +8,7 @@ int main(int argc, char * const argv[])
 {
   int result = TestHarness::EXIT_STATUS_BAD_ARGUMENT;
 
-  const char* optString = "rs";
+  const char* optString = "sf";
   bool optRerunFailed(true);
   bool optRunSerially(false);
 
@@ -18,8 +18,8 @@ int main(int argc, char * const argv[])
     nextOpt = getopt( argc, argv, optString );
     switch(nextOpt)
     {
-      case 'r':
-        optRerunFailed = true;
+      case 'f':
+        optRerunFailed = false;
         break;
       case 's':
         optRunSerially = true;
index b651450..d839c4f 100644 (file)
@@ -8,7 +8,7 @@ int main(int argc, char * const argv[])
 {
   int result = TestHarness::EXIT_STATUS_BAD_ARGUMENT;
 
-  const char* optString = "rs";
+  const char* optString = "sf";
   bool optRerunFailed(true);
   bool optRunSerially(false);
 
@@ -18,8 +18,8 @@ int main(int argc, char * const argv[])
     nextOpt = getopt( argc, argv, optString );
     switch(nextOpt)
     {
-      case 'r':
-        optRerunFailed = true;
+      case 'f':
+        optRerunFailed = false;
         break;
       case 's':
         optRunSerially = true;
index bf01089..496a96f 100644 (file)
@@ -407,15 +407,13 @@ libdali_adaptor_la_LIBADD = \
                       -ljpeg
 
 # EVAS used indicator
-libdali_adaptor_la_CXXFLAGS += $(ELEMENTARY_CFLAGS) \
-                               $(EVAS_CFLAGS) \
+libdali_adaptor_la_CXXFLAGS += $(EVAS_CFLAGS) \
                                $(ECORE_CFLAGS) \
                                $(ECORE_IPC_CFLAGS) \
                                $(ELDBUS_CFLAGS)
 
 
-libdali_adaptor_la_LIBADD += $(ELEMENTARY_LIBS) \
-                             $(ECORE_IPC_LIBS) \
+libdali_adaptor_la_LIBADD += $(ECORE_IPC_LIBS) \
                              $(ELDBUS_LIBS)
 
 if USE_APPFW
@@ -432,15 +430,25 @@ libdali_adaptor_la_LIBADD += $(CAPI_APPFW_APPLICATION_LIBS) \
                              $(TTS_LIBS) \
                              $(SENSOR_LIBS)
 if USE_APPFW_EFL_BASE
+libdali_adaptor_la_CXXFLAGS += $(ELEMENTARY_CFLAGS)
+
+libdali_adaptor_la_LIBADD += $(ELEMENTARY_LIBS)
+
 else
 libdali_adaptor_la_CXXFLAGS += $(CAPI_APPFW_COMMON_CFLAGS) \
                                $(CAPI_APPFW_CONTROL_CFLAGS) \
+                               $(ECORE_IMF_CFLAGS) \
                                $(FRIBIDI_CFLAGS)
 
 libdali_adaptor_la_LIBADD += $(CAPI_APPFW_COMMON_LIBS) \
                              $(CAPI_APPFW_CONTROL_LIBS) \
+                             $(ECORE_IMF_LIBS) \
                              $(FRIBIDI_LIBS)
 endif
+else
+libdali_adaptor_la_CXXFLAGS += $(ELEMENTARY_CFLAGS)
+
+libdali_adaptor_la_LIBADD += $(ELEMENTARY_LIBS)
 endif
 
 if WAYLAND
index c0c71e9..2e5000c 100644 (file)
@@ -46,6 +46,7 @@ PKG_CHECK_MODULES(LIBDRM, libdrm)
 PKG_CHECK_MODULES(LIBCURL, libcurl)
 PKG_CHECK_MODULES(HARFBUZZ, harfbuzz)
 PKG_CHECK_MODULES(FRIBIDI, fribidi)
+PKG_CHECK_MODULES(EVAS, evas)
 PKG_CHECK_MODULES(TTRACE,  ttrace, AC_DEFINE(ENABLE_TTRACE, 1, [ttrace available]),
                   [ AC_MSG_NOTICE([Tizen Trace not avaiable]) ]
                   )
@@ -55,7 +56,6 @@ PKG_CHECK_MODULES(TTRACE,  ttrace, AC_DEFINE(ENABLE_TTRACE, 1, [ttrace available
 PKG_CHECK_MODULES(ECORE, ecore)
 PKG_CHECK_MODULES(ECORE_IPC, ecore-ipc)
 PKG_CHECK_MODULES(ECORE_IMF, [ecore-imf >= 1.13], [ecore_imf_1_13=yes], [ecore_imf_1_13=no])
-PKG_CHECK_MODULES(ELEMENTARY, elementary)
 # Check for EldBus.h in ECore
 PKG_CHECK_MODULES(ELDBUS, eldbus, [ eldbus_available=yes ],  [ eldbus_available=no ] )
 
@@ -248,11 +248,14 @@ if test "x$enable_appfw" = "xyes"; then
 PKG_CHECK_MODULES(CAPI_SYSTEM_SYSTEM_SETTINGS, capi-system-system-settings)
 if test "x$enable_tizen_major_version" = "x3"; then
 PKG_CHECK_MODULES(CAPI_APPFW_APPLICATION, capi-appfw-application)
+PKG_CHECK_MODULES(ELEMENTARY, elementary)
 else
 PKG_CHECK_MODULES(CAPI_APPFW_APPLICATION, appcore-ui)
 PKG_CHECK_MODULES(CAPI_APPFW_COMMON, capi-appfw-app-common)
 PKG_CHECK_MODULES(CAPI_APPFW_CONTROL, capi-appfw-app-control)
 fi
+else
+PKG_CHECK_MODULES(ELEMENTARY, elementary)
 fi
 
 # Using EFL api's for  WAYLAND AND X11 to run on ecore mainloop
index c7029d6..4b1ef3c 100644 (file)
@@ -19,7 +19,7 @@
 
 Name:       dali-adaptor
 Summary:    The DALi Tizen Adaptor
-Version:    1.2.52
+Version:    1.2.54
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT
@@ -104,14 +104,15 @@ BuildRequires:  pkgconfig(utilX)
 
 # for dali-adaptor
 BuildRequires:  pkgconfig(evas)
-BuildRequires:  pkgconfig(elementary)
 
 %if 0%{?tizen_version_major} == 3
 BuildRequires:  pkgconfig(capi-appfw-application)
+BuildRequires:  pkgconfig(elementary)
 %else
 BuildRequires:  pkgconfig(appcore-ui)
 BuildRequires:  pkgconfig(capi-appfw-app-common)
 BuildRequires:  pkgconfig(capi-appfw-app-control)
+BuildRequires:  pkgconfig(ecore-imf)
 %endif
 BuildRequires:  pkgconfig(capi-system-system-settings)
 
old mode 100644 (file)
new mode 100755 (executable)
index e6fdcde..89bca77
@@ -299,7 +299,20 @@ bool LoadBitmapFromPng( const ImageLoader::Input& input, Integration::Bitmap& bi
   if( rowBytes > stride )
   {
     stride = GetTextureDimension(rowBytes);
-    bufferWidth = stride / bpp;
+
+    bpp = stride / bufferWidth;
+    switch(bpp)
+    {
+      case 3:
+        pixelFormat = Pixel::RGB888;
+        break;
+      case 4:
+        pixelFormat = Pixel::RGBA8888;
+        break;
+      default:
+        break;
+    }
+
   }
 
   // decode the whole image into bitmap buffer
index 3006d47..9c56a45 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -110,6 +110,11 @@ PointSize26Dot6 FontClient::GetPointSize( FontId id )
   return GetImplementation(*this).GetPointSize( id );
 }
 
+bool FontClient::IsCharacterSupportedByFont( FontId fontId, Character character )
+{
+  return GetImplementation(*this).IsCharacterSupportedByFont( fontId, character );
+}
+
 FontId FontClient::FindDefaultFont( Character charcode,
                                     PointSize26Dot6 requestedPointSize,
                                     bool preferColor )
index 8b0164e..0a8474d 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_PLATFORM_TEXT_ABSTRACTION_FONT_CLIENT_H
 
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -200,6 +200,16 @@ public:
   PointSize26Dot6 GetPointSize( FontId id );
 
   /**
+   * @brief Whether the given @p character is supported by the font.
+   *
+   * @param[in] fontId The id of the font.
+   * @param[in] character The character.
+   *
+   * @return @e true if the character is supported by the font.
+   */
+  bool IsCharacterSupportedByFont( FontId fontId, Character character );
+
+  /**
    * @brief Find the default font for displaying a UTF-32 character.
    *
    * This is useful when localised strings are provided for multiple languages
index d84e4de..c131160 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -25,7 +25,7 @@
 namespace
 {
 #if defined(DEBUG_ENABLED)
-Dali::Integration::Log::Filter* gLogFilter = Dali::Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_FONT_CLIENT");
+Dali::Integration::Log::Filter* gLogFilter = Dali::Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_FONT_CLIENT_VALUE_TO_INDEX");
 #endif
 }
 
index 52d7898..91071f7 100644 (file)
@@ -1,5 +1,8 @@
+#ifndef DALI_INTERNAL_TEXT_ABSTRACTION_FONT_CLIENT_HELPER_H
+#define DALI_INTERNAL_TEXT_ABSTRACTION_FONT_CLIENT_HELPER_H
+
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -15,9 +18,6 @@
  *
  */
 
-#ifndef __DALI_INTERNAL_TEXT_ABSTRACTION_FONT_CLIENT_HELPER_H__
-#define __DALI_INTERNAL_TEXT_ABSTRACTION_FONT_CLIENT_HELPER_H__
-
 namespace Dali
 {
 
@@ -44,4 +44,4 @@ int ValueToIndex( int value, const int* const table, unsigned int maxIndex );
 
 } // Dali
 
-#endif // __DALI_INTERNAL_TEXT_ABSTRACTION_FONT_CLIENT_HELPER_H__
+#endif // DALI_INTERNAL_TEXT_ABSTRACTION_FONT_CLIENT_HELPER_H
index b850b7f..2c9948b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -137,6 +137,13 @@ PointSize26Dot6 FontClient::GetPointSize( FontId id )
   return mPlugin->GetPointSize( id );
 }
 
+bool FontClient::IsCharacterSupportedByFont( FontId fontId, Character character )
+{
+  CreatePlugin();
+
+  return mPlugin->IsCharacterSupportedByFont( fontId, character );
+}
+
 void FontClient::GetSystemFonts( FontList& systemFonts )
 {
   CreatePlugin();
@@ -203,8 +210,8 @@ FontId FontClient::GetFontId( const FontPath& path, PointSize26Dot6 requestedPoi
 
   return mPlugin->GetFontId( path,
                              requestedPointSize,
-                             requestedPointSize,
-                             faceIndex );
+                             faceIndex,
+                             true );
 }
 
 FontId FontClient::GetFontId( const FontDescription& fontDescription,
@@ -215,7 +222,6 @@ FontId FontClient::GetFontId( const FontDescription& fontDescription,
 
   return mPlugin->GetFontId( fontDescription,
                              requestedPointSize,
-                             requestedPointSize,
                              faceIndex );
 }
 
index 3222526..a13715c 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_INTERNAL_TEXT_ABSTRACTION_FONT_CLIENT_IMPL_H__
-#define __DALI_INTERNAL_TEXT_ABSTRACTION_FONT_CLIENT_IMPL_H__
+#ifndef DALI_INTERNAL_TEXT_ABSTRACTION_FONT_CLIENT_IMPL_H
+#define DALI_INTERNAL_TEXT_ABSTRACTION_FONT_CLIENT_IMPL_H
 
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -101,6 +101,11 @@ public:
   PointSize26Dot6 GetPointSize( FontId id );
 
   /**
+   * @copydoc Dali::TextAbstraction::FontClient::IsCharacterSupportedByFont()
+   */
+  bool IsCharacterSupportedByFont( FontId fontId, Character character );
+
+  /**
    * @copydoc Dali::TextAbstraction::FontClient::FindDefaultFont()
    */
   FontId FindDefaultFont( Character charcode,
@@ -232,4 +237,4 @@ inline static const Internal::FontClient& GetImplementation(const FontClient& fo
 
 } // namespace Dali
 
-#endif // __DALI_INTERNAL_TEXT_ABSTRACTION_FONT_CLIENT_IMPL_H__
+#endif // DALI_INTERNAL_TEXT_ABSTRACTION_FONT_CLIENT_IMPL_H
index 501641f..6e7d294 100644 (file)
@@ -52,8 +52,6 @@ const int DEFAULT_FONT_SLANT  =   0; // normal
 
 const uint32_t ELLIPSIS_CHARACTER = 0x2026;
 
-const bool FONT_FIXED_SIZE_BITMAP( true );
-
 // http://www.freedesktop.org/software/fontconfig/fontconfig-user.html
 
 // NONE            -1  --> DEFAULT_FONT_WIDTH (NORMAL) will be used.
@@ -140,9 +138,10 @@ FontSlant::Type IntToSlantType( int slant )
   return static_cast<FontSlant::Type>( ValueToIndex( slant, FONT_SLANT_TYPE_TO_INT, NUM_FONT_SLANT_TYPE - 1u ) );
 }
 
-FontClient::Plugin::FallbackCacheItem::FallbackCacheItem( const FontDescription& font, FontList* list )
+  FontClient::Plugin::FallbackCacheItem::FallbackCacheItem( const FontDescription& font, FontList* fallbackFonts, CharacterSetList* characterSets )
 : fontDescription( font ),
-  fallbackFonts( list )
+  fallbackFonts( fallbackFonts ),
+  characterSets( characterSets )
 {
 }
 
@@ -172,10 +171,12 @@ FontClient::Plugin::FontFaceCacheItem::FontFaceCacheItem( FT_Face ftFace,
   mRequestedPointSize( requestedPointSize ),
   mFaceIndex( face ),
   mMetrics( metrics ),
+  mCharacterSet( NULL ),
   mFixedWidthPixels( 0.0f ),
   mFixedHeightPixels( 0.0f ),
   mVectorFontId( 0 ),
-  mIsFixedSizeBitmap( false )
+  mIsFixedSizeBitmap( false ),
+  mHasColorTables( false )
 {
 }
 
@@ -185,16 +186,19 @@ FontClient::Plugin::FontFaceCacheItem::FontFaceCacheItem( FT_Face ftFace,
                                                           FaceIndex face,
                                                           const FontMetrics& metrics,
                                                           float fixedWidth,
-                                                          float fixedHeight )
+                                                          float fixedHeight,
+                                                          bool hasColorTables )
 : mFreeTypeFace( ftFace ),
   mPath( path ),
   mRequestedPointSize( requestedPointSize ),
   mFaceIndex( face ),
   mMetrics( metrics ),
+  mCharacterSet( NULL ),
   mFixedWidthPixels( fixedWidth ),
   mFixedHeightPixels( fixedHeight ),
   mVectorFontId( 0 ),
-  mIsFixedSizeBitmap( true )
+  mIsFixedSizeBitmap( true ),
+  mHasColorTables( hasColorTables )
 {
 }
 
@@ -209,15 +213,18 @@ FontClient::Plugin::Plugin( unsigned int horizontalDpi,
   mFontCache(),
   mValidatedFontCache(),
   mFontDescriptionCache( 1u ),
+  mCharacterSetCache(),
   mFontIdCache(),
   mVectorFontCache( NULL ),
   mEllipsisCache(),
   mDefaultFontDescriptionCached( false )
 {
+  mCharacterSetCache.Resize( 1u );
+
   int error = FT_Init_FreeType( &mFreeTypeLibrary );
   if( FT_Err_Ok != error )
   {
-    DALI_LOG_ERROR( "FreeType Init error: %d\n", error );
+    DALI_LOG_INFO( gLogFilter, Debug::General, "FreeType Init error: %d\n", error );
   }
 
 #ifdef ENABLE_VECTOR_BASED_TEXT_RENDERING
@@ -236,7 +243,9 @@ FontClient::Plugin::~Plugin()
     if( item.fallbackFonts )
     {
       delete item.fallbackFonts;
+      delete item.characterSets;
       item.fallbackFonts = NULL;
+      item.characterSets = NULL;
     }
   }
 
@@ -259,9 +268,13 @@ void FontClient::Plugin::ResetSystemDefaults()
   mDefaultFontDescriptionCached = false;
 }
 
-void FontClient::Plugin::SetFontList( const FontDescription& fontDescription, FontList& fontList )
+void FontClient::Plugin::SetFontList( const FontDescription& fontDescription, FontList& fontList, CharacterSetList& characterSetList )
 {
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "FontClient::Plugin::SetFontList family(%s)\n", fontDescription.family.c_str() );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "-->FontClient::Plugin::SetFontList\n" );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  description; family : [%s]\n", fontDescription.family.c_str() );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                width : [%s]\n", FontWidth::Name[fontDescription.width] );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "               weight : [%s]\n", FontWeight::Name[fontDescription.weight] );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                slant : [%s]\n\n", FontSlant::Name[fontDescription.slant] );
 
   fontList.clear();
 
@@ -278,6 +291,7 @@ void FontClient::Plugin::SetFontList( const FontDescription& fontDescription, Fo
 
   if( NULL != fontSet )
   {
+    DALI_LOG_INFO( gLogFilter, Debug::General, "  number of fonts found : [%d]\n", fontSet->nfont );
     // Reserve some space to avoid reallocations.
     fontList.reserve( fontSet->nfont );
 
@@ -290,6 +304,10 @@ void FontClient::Plugin::SetFontList( const FontDescription& fontDescription, Fo
       // Skip fonts with no path
       if( GetFcString( fontPattern, FC_FILE, path ) )
       {
+        FcCharSet* characterSet = NULL;
+        FcPatternGetCharSet( fontPattern, FC_CHARSET, 0u, &characterSet );
+
+        characterSetList.PushBack( characterSet );
         fontList.push_back( FontDescription() );
         FontDescription& newFontDescription = fontList.back();
 
@@ -305,18 +323,29 @@ void FontClient::Plugin::SetFontList( const FontDescription& fontDescription, Fo
         newFontDescription.width = IntToWidthType( width );
         newFontDescription.weight = IntToWeightType( weight );
         newFontDescription.slant = IntToSlantType( slant );
+
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "  description; family : [%s]\n", newFontDescription.family.c_str() );
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                 path : [%s]\n", newFontDescription.path.c_str() );
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                width : [%s]\n", FontWidth::Name[newFontDescription.width] );
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "               weight : [%s]\n", FontWeight::Name[newFontDescription.weight] );
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                slant : [%s]\n\n", FontSlant::Name[newFontDescription.slant] );
       }
     }
 
     FcFontSetDestroy( fontSet );
   }
+  else
+  {
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "  No fonts found.\n" );
+  }
 
   FcPatternDestroy( fontFamilyPattern );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "<--FontClient::Plugin::SetFontList\n" );
 }
 
 void FontClient::Plugin::GetDefaultFonts( FontList& defaultFonts )
 {
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "FontClient::Plugin::GetDefaultFonts mDefaultFonts(%s)\n", ( mDefaultFonts.empty()?"empty":"valid" ) );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "-->FontClient::Plugin::GetDefaultFonts\n" );
 
   if( mDefaultFonts.empty() )
   {
@@ -325,19 +354,42 @@ void FontClient::Plugin::GetDefaultFonts( FontList& defaultFonts )
     fontDescription.width = IntToWidthType( DEFAULT_FONT_WIDTH );
     fontDescription.weight = IntToWeightType( DEFAULT_FONT_WEIGHT );
     fontDescription.slant = IntToSlantType( DEFAULT_FONT_SLANT );
-    SetFontList( fontDescription, mDefaultFonts );
+    SetFontList( fontDescription, mDefaultFonts, mDefaultFontCharacterSets );
   }
 
   defaultFonts = mDefaultFonts;
+
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  number of default fonts : [%d]\n", mDefaultFonts.size() );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "<--FontClient::Plugin::GetDefaultFonts\n" );
 }
 
 void FontClient::Plugin::GetDefaultPlatformFontDescription( FontDescription& fontDescription )
 {
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "FontClient::Plugin::GetDefaultPlatformFontDescription\n");
+  DALI_LOG_INFO( gLogFilter, Debug::General, "-->FontClient::Plugin::GetDefaultPlatformFontDescription\n");
 
   if( !mDefaultFontDescriptionCached )
   {
-    FcInitReinitialize(); // FcInitBringUptoDate did not seem to reload config file as was still getting old default font.
+    // Clear any font config stored info in the caches.
+    mDefaultFontCharacterSets.Clear();
+    mCharacterSetCache.Clear();
+
+    for( std::vector<FallbackCacheItem>::iterator it = mFallbackCache.begin(), endIt = mFallbackCache.end(); it != endIt; ++it )
+    {
+      FallbackCacheItem& item = *it;
+
+      item.characterSets->Clear();
+    }
+
+    for( std::vector<FontFaceCacheItem>::iterator it = mFontCache.begin(), endIt = mFontCache.end(); it != endIt; ++it )
+    {
+      FontFaceCacheItem& item = *it;
+
+      // Set the character set pointer as null. Will be created again the next time IsCharacterSupportedByFont()
+      item.mCharacterSet = NULL;
+    }
+
+    // FcInitBringUptoDate did not seem to reload config file as was still getting old default font.
+    FcInitReinitialize();
 
     FcPattern* matchPattern = FcPatternCreate();
 
@@ -346,10 +398,46 @@ void FontClient::Plugin::GetDefaultPlatformFontDescription( FontDescription& fon
       FcConfigSubstitute( NULL, matchPattern, FcMatchPattern );
       FcDefaultSubstitute( matchPattern );
 
-      MatchFontDescriptionToPattern( matchPattern, mDefaultFontDescription );
+      FcCharSet* characterSet = NULL;
+      MatchFontDescriptionToPattern( matchPattern, mDefaultFontDescription, &characterSet );
       FcPatternDestroy( matchPattern );
     }
 
+    // Create again the character sets as they are not valid after FcInitReinitialize()
+
+    for( FontList::const_iterator it = mDefaultFonts.begin(), endIt = mDefaultFonts.end(); it != endIt; ++it )
+    {
+      const FontDescription& description = *it;
+
+      mDefaultFontCharacterSets.PushBack( CreateCharacterSetFromDescription( description ) );
+    }
+
+    for( FontList::const_iterator it = mFontDescriptionCache.begin(), endIt = mFontDescriptionCache.end(); it != endIt; ++it )
+    {
+      const FontDescription& description = *it;
+
+      mCharacterSetCache.PushBack( CreateCharacterSetFromDescription( description ) );
+    }
+
+    for( std::vector<FallbackCacheItem>::iterator it = mFallbackCache.begin(), endIt = mFallbackCache.end(); it != endIt; ++it )
+    {
+      FallbackCacheItem& item = *it;
+
+      if( NULL != item.fallbackFonts )
+      {
+        if( NULL == item.characterSets )
+        {
+          item.characterSets = new CharacterSetList;
+        }
+
+        for( FontList::const_iterator flIt = item.fallbackFonts->begin(), flEndIt = item.fallbackFonts->end(); flIt != flEndIt; ++flIt )
+        {
+          const FontDescription& description = *flIt;
+          item.characterSets->PushBack( CreateCharacterSetFromDescription( description ) );
+        }
+      }
+    }
+
     mDefaultFontDescriptionCached = true;
   }
 
@@ -358,11 +446,18 @@ void FontClient::Plugin::GetDefaultPlatformFontDescription( FontDescription& fon
   fontDescription.width  = mDefaultFontDescription.width;
   fontDescription.weight = mDefaultFontDescription.weight;
   fontDescription.slant  = mDefaultFontDescription.slant;
+
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  description; family : [%s]\n", fontDescription.family.c_str() );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                 path : [%s]\n", fontDescription.path.c_str() );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                width : [%s]\n", FontWidth::Name[fontDescription.width] );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "               weight : [%s]\n", FontWeight::Name[fontDescription.weight] );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                slant : [%s]\n\n", FontSlant::Name[fontDescription.slant] );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "<--FontClient::Plugin::GetDefaultPlatformFontDescription\n");
 }
 
 void FontClient::Plugin::GetSystemFonts( FontList& systemFonts )
 {
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "FontClient::Plugin::GetSystemFonts\n");
+  DALI_LOG_INFO( gLogFilter, Debug::General, "-->FontClient::Plugin::GetSystemFonts\n");
 
   if( mSystemFonts.empty() )
   {
@@ -370,11 +465,16 @@ void FontClient::Plugin::GetSystemFonts( FontList& systemFonts )
   }
 
   systemFonts = mSystemFonts;
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  number of system fonts : [%d]\n", mSystemFonts.size() );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "<--FontClient::Plugin::GetSystemFonts\n");
 }
 
 void FontClient::Plugin::GetDescription( FontId id,
                                          FontDescription& fontDescription ) const
 {
+  DALI_LOG_INFO( gLogFilter, Debug::General, "-->FontClient::Plugin::GetDescription\n");
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  font id : %d\n", id );
+
   for( std::vector<FontIdCacheItem>::const_iterator it = mFontIdCache.begin(),
          endIt = mFontIdCache.end();
        it != endIt;
@@ -385,103 +485,163 @@ void FontClient::Plugin::GetDescription( FontId id,
     if( item.fontId == id )
     {
       fontDescription = *( mFontDescriptionCache.begin() + item.validatedFontId );
+
+      DALI_LOG_INFO( gLogFilter, Debug::General, "  description; family : [%s]\n", fontDescription.family.c_str() );
+      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                 path : [%s]\n", fontDescription.path.c_str() );
+      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                width : [%s]\n", FontWidth::Name[fontDescription.width] );
+      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "               weight : [%s]\n", FontWeight::Name[fontDescription.weight] );
+      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                slant : [%s]\n\n", FontSlant::Name[fontDescription.slant] );
+      DALI_LOG_INFO( gLogFilter, Debug::General, "<--FontClient::Plugin::GetDescription\n");
       return;
     }
   }
 
-  DALI_LOG_ERROR( "FontClient::Plugin::GetDescription. No description found for the font ID %d\n", id );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  No description found for the font ID %d\n", id );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "<--FontClient::Plugin::GetDescription\n");
 }
 
 PointSize26Dot6 FontClient::Plugin::GetPointSize( FontId id )
 {
+  DALI_LOG_INFO( gLogFilter, Debug::General, "-->FontClient::Plugin::GetPointSize\n");
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  font id : %d\n", id );
   const FontId index = id - 1u;
 
-  if( id > 0u &&
-      index < mFontCache.size() )
+  if( ( id > 0u ) &&
+      ( index < mFontCache.size() ) )
   {
+    DALI_LOG_INFO( gLogFilter, Debug::General, "  point size : %d\n", ( *( mFontCache.begin() + index ) ).mRequestedPointSize );
+    DALI_LOG_INFO( gLogFilter, Debug::General, "<--FontClient::Plugin::GetPointSize\n");
     return ( *( mFontCache.begin() + index ) ).mRequestedPointSize;
   }
   else
   {
-    DALI_LOG_ERROR( "FontClient::Plugin::GetPointSize. Invalid font ID %d\n", id );
+    DALI_LOG_INFO( gLogFilter, Debug::General, "  Invalid font ID %d\n", id );
   }
 
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  default point size : %d\n", TextAbstraction::FontClient::DEFAULT_POINT_SIZE );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "<--FontClient::Plugin::GetPointSize\n");
   return TextAbstraction::FontClient::DEFAULT_POINT_SIZE;
 }
 
+bool FontClient::Plugin::IsCharacterSupportedByFont( FontId fontId, Character character )
+{
+  DALI_LOG_INFO( gLogFilter, Debug::General, "-->FontClient::Plugin::IsCharacterSupportedByFont\n");
+  DALI_LOG_INFO( gLogFilter, Debug::General, "    font id : %d\n", fontId );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  character : %p\n", character );
+
+  if( ( fontId < 1u ) || ( fontId > mFontCache.size() ) )
+  {
+    DALI_LOG_INFO( gLogFilter, Debug::General, "  Invalid font id. Number of items in the cache: %d\n",mFontCache.size());
+    DALI_LOG_INFO( gLogFilter, Debug::General, "<--FontClient::Plugin::IsCharacterSupportedByFont\n");
+    return false;
+  }
+
+  --fontId;
+
+  bool isSupported = false;
+
+  FontFaceCacheItem& cacheItem = mFontCache[fontId];
+
+  if( NULL == cacheItem.mCharacterSet )
+  {
+    // Create again the character set.
+    // It can be null if the ResetSystemDefaults() method has been called.
+
+    FontDescription description;
+    description.path = cacheItem.mPath;
+    description.family = FontFamily( cacheItem.mFreeTypeFace->family_name );
+    description.weight = FontWeight::NONE;
+    description.width = FontWidth::NONE;
+    description.slant = FontSlant::NONE;
+
+    // Note FreeType doesn't give too much info to build a proper font style.
+    if( cacheItem.mFreeTypeFace->style_flags & FT_STYLE_FLAG_ITALIC )
+    {
+      description.slant = FontSlant::ITALIC;
+    }
+    if( cacheItem.mFreeTypeFace->style_flags & FT_STYLE_FLAG_BOLD )
+    {
+      description.weight = FontWeight::BOLD;
+    }
+
+    cacheItem.mCharacterSet = CreateCharacterSetFromDescription( description );
+  }
+
+  isSupported = FcCharSetHasChar( cacheItem.mCharacterSet, character );
+
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  is supported : %s\n", (isSupported ? "true" : "false") );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "<--FontClient::Plugin::IsCharacterSupportedByFont\n");
+  return isSupported;
+}
+
 FontId FontClient::Plugin::FindFontForCharacter( const FontList& fontList,
-                                                 Character charcode,
+                                                 const CharacterSetList& characterSetList,
+                                                 Character character,
                                                  PointSize26Dot6 requestedPointSize,
                                                  bool preferColor )
 {
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "FontClient::Plugin::FindFontForCharacter\n");
+  DALI_ASSERT_DEBUG( ( fontList.size() == characterSetList.Count() ) && "FontClient::Plugin::FindFontForCharacter. Different number of fonts and character sets." );
+
+  DALI_LOG_INFO( gLogFilter, Debug::General, "-->FontClient::Plugin::FindFontForCharacter\n" );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "           character : %p\n", character );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  requestedPointSize : %d\n", requestedPointSize );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "         preferColor : %s\n", ( preferColor ? "true" : "false" ) );
 
   FontId fontId = 0u;
   bool foundColor = false;
 
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  number of fonts : %d\n", fontList.size() );
+
   // Traverse the list of fonts.
   // Check for each font if supports the character.
-  for( FontList::const_iterator it = fontList.begin(), endIt = fontList.end();
-       it != endIt;
-       ++it )
+  for( unsigned int index = 0u, numberOfFonts = fontList.size(); index < numberOfFonts; ++index )
   {
-    const FontDescription& description = *it;
+    const FontDescription& description = fontList[index];
+    const FcCharSet* const characterSet = characterSetList[index];
 
-    FcPattern* pattern = CreateFontFamilyPattern( description );
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "  description; family : [%s]\n", description.family.c_str() );
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                 path : [%s]\n", description.path.c_str() );
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                width : [%s]\n", FontWidth::Name[description.width] );
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "               weight : [%s]\n", FontWeight::Name[description.weight] );
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                slant : [%s]\n\n", FontSlant::Name[description.slant] );
 
-    FcResult result = FcResultMatch;
-    FcPattern* match = FcFontMatch( NULL /* use default configure */, pattern, &result );
-
-    FcCharSet* charSet = NULL;
-    FcPatternGetCharSet( match, FC_CHARSET, 0u, &charSet );
-
-    if( FcCharSetHasChar( charSet, charcode ) )
+    bool foundInRanges = false;
+    if( NULL != characterSet )
     {
-      Vector< PointSize26Dot6 > fixedSizes;
-      GetFixedSizes( description,
-                     fixedSizes );
-
-      PointSize26Dot6 actualPointSize = requestedPointSize;
-
-      const Vector< PointSize26Dot6 >::SizeType count = fixedSizes.Count();
-
-      if( 0 != count )
-      {
-        // If the font is not scalable, pick the largest size <= requestedPointSize
-        actualPointSize = fixedSizes[0];
-        for( unsigned int i=1; i<count; ++i )
-        {
-          if( fixedSizes[i] <= requestedPointSize &&
-              fixedSizes[i] > actualPointSize )
-          {
-            actualPointSize = fixedSizes[i];
-          }
-        }
-      }
+      foundInRanges = FcCharSetHasChar( characterSet, character );
+    }
 
+    if( foundInRanges )
+    {
       fontId = GetFontId( description,
                           requestedPointSize,
-                          actualPointSize,
                           0u );
 
+      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "     font id : %d\n", fontId );
+
       if( preferColor )
       {
-        foundColor = IsColorGlyph( fontId, GetGlyphIndex( fontId, charcode ) );
+        if( ( fontId > 0 ) &&
+            ( fontId - 1u < mFontCache.size() ) )
+        {
+          const FontFaceCacheItem& item = mFontCache[fontId - 1u];
+
+          foundColor = item.mHasColorTables;
+        }
+
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "  foundColor : %s\n", ( foundColor ? "true" : "false" ) );
       }
 
       // Keep going unless we prefer a different (color) font.
       if( !preferColor || foundColor )
       {
-        FcPatternDestroy( match );
-        FcPatternDestroy( pattern );
         break;
       }
     }
-
-    FcPatternDestroy( match );
-    FcPatternDestroy( pattern );
   }
 
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  font id : %d\n", fontId );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "<--FontClient::Plugin::FindFontForCharacter\n" );
   return fontId;
 }
 
@@ -489,7 +649,10 @@ FontId FontClient::Plugin::FindDefaultFont( Character charcode,
                                             PointSize26Dot6 requestedPointSize,
                                             bool preferColor )
 {
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "FontClient::Plugin::FindDefaultFont DefaultFontsList(%s)\n", (mDefaultFonts.empty()?"empty":"created") );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "-->FontClient::Plugin::FindDefaultFont\n" );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "           character : %p\n", charcode );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  requestedPointSize : %d\n", requestedPointSize );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "         preferColor : %s\n", ( preferColor ? "true" : "false" ) );
 
   FontId fontId(0);
 
@@ -502,12 +665,17 @@ FontId FontClient::Plugin::FindDefaultFont( Character charcode,
     fontDescription.weight = IntToWeightType( DEFAULT_FONT_WEIGHT );
     fontDescription.slant = IntToSlantType( DEFAULT_FONT_SLANT );
 
-    SetFontList( fontDescription, mDefaultFonts );
+    SetFontList( fontDescription, mDefaultFonts, mDefaultFontCharacterSets );
   }
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "  number of default fonts : %d\n", mDefaultFonts.size() );
+
 
   // Traverse the list of default fonts.
   // Check for each default font if supports the character.
-  fontId = FindFontForCharacter( mDefaultFonts, charcode, requestedPointSize, preferColor );
+  fontId = FindFontForCharacter( mDefaultFonts, mDefaultFontCharacterSets, charcode, requestedPointSize, preferColor );
+
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  font id : %d\n", fontId );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "<--FontClient::Plugin::FindDefaultFont\n" );
 
   return fontId;
 }
@@ -517,6 +685,11 @@ FontId FontClient::Plugin::FindFallbackFont( Character charcode,
                                              PointSize26Dot6 requestedPointSize,
                                              bool preferColor )
 {
+  DALI_LOG_INFO( gLogFilter, Debug::General, "-->FontClient::Plugin::FindFallbackFont\n" );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "           character : %p\n", charcode );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  requestedPointSize : %d\n", requestedPointSize );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "         preferColor : %s\n", ( preferColor ? "true" : "false" ) );
+
   // The font id to be returned.
   FontId fontId = 0u;
 
@@ -528,33 +701,45 @@ FontId FontClient::Plugin::FindFallbackFont( Character charcode,
   fontDescription.width = ( ( FontWidth::NONE == preferredFontDescription.width ) ? IntToWidthType( DEFAULT_FONT_WIDTH ) : preferredFontDescription.width );
   fontDescription.slant = ( ( FontSlant::NONE == preferredFontDescription.slant ) ? IntToSlantType( DEFAULT_FONT_SLANT ) : preferredFontDescription.slant );
 
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  preferredFontDescription --> fontDescription\n" );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  [%s] --> [%s]\n", preferredFontDescription.family.c_str(), fontDescription.family.c_str() );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "  [%s] --> [%s]\n", FontWeight::Name[preferredFontDescription.weight], FontWeight::Name[fontDescription.weight] );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "  [%s] --> [%s]\n", FontWidth::Name[preferredFontDescription.width], FontWidth::Name[fontDescription.width] );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "  [%s] --> [%s]\n", FontSlant::Name[preferredFontDescription.slant], FontSlant::Name[fontDescription.slant] );
+
   // Check first if the font's description has been queried before.
-  FontList* fontList( NULL );
+  FontList* fontList = NULL;
+  CharacterSetList* characterSetList = NULL;
 
-  if( !FindFallbackFontList( fontDescription, fontList ) )
+  if( !FindFallbackFontList( fontDescription, fontList, characterSetList ) )
   {
     fontList = new FontList;
-    SetFontList( fontDescription, *fontList );
+    characterSetList = new CharacterSetList;
+
+    SetFontList( fontDescription, *fontList, *characterSetList );
 
     // Add the font-list to the cache.
-    mFallbackCache.push_back( FallbackCacheItem( fontDescription, fontList ) );
+    mFallbackCache.push_back( FallbackCacheItem( fontDescription, fontList, characterSetList ) );
   }
 
-  if( fontList )
+  if( fontList && characterSetList )
   {
-    fontId = FindFontForCharacter( *fontList, charcode, requestedPointSize, preferColor );
+    fontId = FindFontForCharacter( *fontList, *characterSetList, charcode, requestedPointSize, preferColor );
   }
 
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  font id : %d\n", fontId );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "<--FontClient::Plugin::FindFallbackFont\n");
   return fontId;
 }
 
 FontId FontClient::Plugin::GetFontId( const FontPath& path,
                                       PointSize26Dot6 requestedPointSize,
-                                      PointSize26Dot6 actualPointSize,
                                       FaceIndex faceIndex,
                                       bool cacheDescription )
 {
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "FontClient::Plugin::GetFontId fontPatch:%s\n", path.c_str() );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "-->FontClient::Plugin::GetFontId\n" );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "                path : [%s]\n", path.c_str() );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  requestedPointSize : %d\n", requestedPointSize );
 
   FontId id( 0 );
 
@@ -567,19 +752,27 @@ FontId FontClient::Plugin::GetFontId( const FontPath& path,
     }
     else
     {
-      id = CreateFont( path, requestedPointSize, actualPointSize, faceIndex, cacheDescription );
+      id = CreateFont( path, requestedPointSize, faceIndex, cacheDescription );
     }
   }
 
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  font id : %d\n", id );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "<--FontClient::Plugin::GetFontId\n" );
+
   return id;
 }
 
 FontId FontClient::Plugin::GetFontId( const FontDescription& fontDescription,
                                       PointSize26Dot6 requestedPointSize,
-                                      PointSize26Dot6 actualPointSize,
                                       FaceIndex faceIndex )
 {
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "FontClient::Plugin::GetFontId font family(%s)\n", fontDescription.family.c_str() );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "-->FontClient::Plugin::GetFontId\n" );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  description; family : [%s]\n", fontDescription.family.c_str() );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                 path : [%s]\n", fontDescription.path.c_str() );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                width : [%s]\n", FontWidth::Name[fontDescription.width] );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "               weight : [%s]\n", FontWeight::Name[fontDescription.weight] );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                slant : [%s]\n\n", FontSlant::Name[fontDescription.slant] );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "   requestedPointSize : %d\n", requestedPointSize );
 
   // This method uses three vectors which caches:
   // * Pairs of non validated font descriptions and an index to a vector with paths to font file names.
@@ -605,8 +798,6 @@ FontId FontClient::Plugin::GetFontId( const FontDescription& fontDescription,
   if( !FindValidatedFont( fontDescription,
                           validatedFontId ) )
   {
-    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "FontClient::Plugin::GetFontId Validating Font\n");
-
     // Use font config to validate the font's description.
     ValidateFont( fontDescription,
                   validatedFontId );
@@ -621,39 +812,57 @@ FontId FontClient::Plugin::GetFontId( const FontDescription& fontDescription,
     // Retrieve the font id. Do not cache the description as it has been already cached.
     fontId = GetFontId( description.path,
                         requestedPointSize,
-                        actualPointSize,
                         faceIndex,
                         false );
 
+    mFontCache[fontId-1u].mCharacterSet = mCharacterSetCache[validatedFontId];
+
     // Cache the pair 'validatedFontId, requestedPointSize' to improve the following queries.
     mFontIdCache.push_back( FontIdCacheItem( validatedFontId,
                                              requestedPointSize,
                                              fontId ) );
   }
 
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  font id : %d\n", fontId );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "<--FontClient::Plugin::GetFontId\n" );
+
   return fontId;
 }
 
 void FontClient::Plugin::ValidateFont( const FontDescription& fontDescription,
                                        FontDescriptionId& validatedFontId )
 {
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "FontClient::Plugin::ValidateFont Validating Font family(%s) \n", fontDescription.family.c_str() );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "-->FontClient::Plugin::ValidateFont\n" );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  description; family : [%s]\n", fontDescription.family.c_str() );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                 path : [%s]\n", fontDescription.path.c_str() );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                width : [%s]\n", FontWidth::Name[fontDescription.width] );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "               weight : [%s]\n", FontWeight::Name[fontDescription.weight] );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                slant : [%s]\n\n", FontSlant::Name[fontDescription.slant] );
 
   // Create a font pattern.
   FcPattern* fontFamilyPattern = CreateFontFamilyPattern( fontDescription );
 
   FontDescription description;
 
-  bool matched = MatchFontDescriptionToPattern( fontFamilyPattern, description );
+  FcCharSet* characterSet = NULL;
+  bool matched = MatchFontDescriptionToPattern( fontFamilyPattern, description, &characterSet );
   FcPatternDestroy( fontFamilyPattern );
 
-  if( matched )
+  if( matched && ( NULL != characterSet ) )
   {
     // Set the index to the vector of paths to font file names.
     validatedFontId = mFontDescriptionCache.size();
 
+    DALI_LOG_INFO( gLogFilter, Debug::General, "  matched description; family : [%s]\n", description.family.c_str() );
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                         path : [%s]\n", description.path.c_str() );
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                        width : [%s]\n", FontWidth::Name[description.width] );
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                       weight : [%s]\n", FontWeight::Name[description.weight] );
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                        slant : [%s]\n\n", FontSlant::Name[description.slant] );
+    DALI_LOG_INFO( gLogFilter, Debug::General, "  validatedFontId : %d\n", validatedFontId );
+
     // Add the path to the cache.
     mFontDescriptionCache.push_back( description );
+    mCharacterSetCache.PushBack( characterSet );
 
     // Cache the index and the matched font's description.
     FontDescriptionCacheItem item( description,
@@ -675,14 +884,10 @@ void FontClient::Plugin::ValidateFont( const FontDescription& fontDescription,
   }
   else
   {
-    DALI_LOG_ERROR( "FontClient::Plugin::ValidateFont failed for font %s %d %d %d\n",
-                    fontDescription.family.c_str(),
-                    fontDescription.width,
-                    fontDescription.weight,
-                    fontDescription.slant );
+    DALI_LOG_INFO( gLogFilter, Debug::General, "  font validation failed for font [%s]\n", fontDescription.family.c_str() );
   }
 
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "FontClient::Plugin::ValidateFont validatedFontId(%u) font family(%s)\n", validatedFontId, fontDescription.family.c_str() );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "<--FontClient::Plugin::ValidateFont\n" );
 }
 
 void FontClient::Plugin::GetFontMetrics( FontId fontId,
@@ -714,19 +919,19 @@ void FontClient::Plugin::GetFontMetrics( FontId fontId,
   }
   else
   {
-    DALI_LOG_ERROR( "Invalid font ID %d\n", fontId );
+    DALI_LOG_INFO( gLogFilter, Debug::General, "FontClient::Plugin::GetFontMetrics. Invalid font id : %d\n", fontId );
   }
 }
 
 GlyphIndex FontClient::Plugin::GetGlyphIndex( FontId fontId,
                                               Character charcode )
 {
-  GlyphIndex index( 0 );
+  GlyphIndex index = 0u;
 
-  if( fontId > 0 &&
-      fontId-1 < mFontCache.size() )
+  if( ( fontId > 0u ) &&
+      ( fontId - 1u < mFontCache.size() ) )
   {
-    FT_Face ftFace = mFontCache[fontId-1].mFreeTypeFace;
+    FT_Face ftFace = mFontCache[fontId-1u].mFreeTypeFace;
 
     index = FT_Get_Char_Index( ftFace, charcode );
   }
@@ -797,7 +1002,7 @@ bool FontClient::Plugin::GetBitmapMetrics( GlyphInfo* array,
         }
         else
         {
-          DALI_LOG_ERROR( "FreeType Bitmap Load_Glyph error %d\n", error );
+          DALI_LOG_INFO( gLogFilter, Debug::General, "FontClient::Plugin::GetBitmapMetrics. FreeType Bitmap Load_Glyph error %d\n", error );
           success = false;
         }
       }
@@ -917,7 +1122,7 @@ void FontClient::Plugin::CreateBitmap( FontId fontId, GlyphIndex glyphIndex, Dal
           }
           else
           {
-            DALI_LOG_ERROR( "FT_Get_Glyph Failed with error: %d\n", error );
+            DALI_LOG_INFO( gLogFilter, Debug::General, "FontClient::Plugin::CreateBitmap. FT_Get_Glyph Failed with error: %d\n", error );
           }
         }
         else
@@ -931,7 +1136,7 @@ void FontClient::Plugin::CreateBitmap( FontId fontId, GlyphIndex glyphIndex, Dal
     }
     else
     {
-      DALI_LOG_ERROR( "FT_Load_Glyph Failed with error: %d\n", error );
+      DALI_LOG_INFO( gLogFilter, Debug::General, "FontClient::Plugin::CreateBitmap. FT_Load_Glyph Failed with error: %d\n", error );
     }
   }
 }
@@ -974,6 +1179,9 @@ void FontClient::Plugin::CreateVectorBlob( FontId fontId, GlyphIndex glyphIndex,
 
 const GlyphInfo& FontClient::Plugin::GetEllipsisGlyph( PointSize26Dot6 requestedPointSize )
 {
+  DALI_LOG_INFO( gLogFilter, Debug::General, "-->FontClient::Plugin::GetEllipsisGlyph\n" );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  requestedPointSize %d.\n", requestedPointSize );
+
   // First look into the cache if there is an ellipsis glyph for the requested point size.
   for( Vector<EllipsisItem>::ConstIterator it = mEllipsisCache.Begin(),
          endIt = mEllipsisCache.End();
@@ -985,6 +1193,11 @@ const GlyphInfo& FontClient::Plugin::GetEllipsisGlyph( PointSize26Dot6 requested
     if( fabsf( item.requestedPointSize - requestedPointSize ) < Math::MACHINE_EPSILON_1000 )
     {
       // Use the glyph in the cache.
+
+      DALI_LOG_INFO( gLogFilter, Debug::General, "  glyph id %d found in the cache.\n", item.glyph.index );
+      DALI_LOG_INFO( gLogFilter, Debug::General, "      font %d.\n", item.glyph.fontId );
+      DALI_LOG_INFO( gLogFilter, Debug::General, "<--FontClient::Plugin::GetEllipsisGlyph\n" );
+
       return item.glyph;
     }
   }
@@ -1006,6 +1219,10 @@ const GlyphInfo& FontClient::Plugin::GetEllipsisGlyph( PointSize26Dot6 requested
 
   GetBitmapMetrics( &item.glyph, 1u, true );
 
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  glyph id %d found in the cache.\n", item.glyph.index );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "      font %d.\n", item.glyph.fontId );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "<--FontClient::Plugin::GetEllipsisGlyph\n" );
+
   return item.glyph;
 }
 
@@ -1021,7 +1238,7 @@ bool FontClient::Plugin::IsColorGlyph( FontId fontId, GlyphIndex glyphIndex )
     FT_Face ftFace = item.mFreeTypeFace;
 
     // Check to see if this is fixed size bitmap
-    if( item.mIsFixedSizeBitmap )
+    if( item.mHasColorTables )
     {
       error = FT_Load_Glyph( ftFace, glyphIndex, FT_LOAD_COLOR );
     }
@@ -1033,12 +1250,14 @@ bool FontClient::Plugin::IsColorGlyph( FontId fontId, GlyphIndex glyphIndex )
 
 void FontClient::Plugin::InitSystemFonts()
 {
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "FontClient::Plugin::InitSystemFonts \n");
+  DALI_LOG_INFO( gLogFilter, Debug::General, "-->FontClient::Plugin::InitSystemFonts\n" );
 
   FcFontSet* fontSet = GetFcFontSet();
 
   if( fontSet )
   {
+    DALI_LOG_INFO( gLogFilter, Debug::General, "  number of system fonts : %d\n", fontSet->nfont );
+
     // Reserve some space to avoid reallocations.
     mSystemFonts.reserve( fontSet->nfont );
 
@@ -1066,30 +1285,37 @@ void FontClient::Plugin::InitSystemFonts()
         fontDescription.width = IntToWidthType( width );
         fontDescription.weight = IntToWeightType( weight );
         fontDescription.slant = IntToSlantType( slant );
-        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "FontClient::Plugin::InitSystemFonts font family(%s)\n", fontDescription.family.c_str() );
 
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "  description; family : [%s]\n", fontDescription.family.c_str() );
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                 path : [%s]\n", fontDescription.path.c_str() );
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                width : [%s]\n", FontWidth::Name[fontDescription.width] );
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "               weight : [%s]\n", FontWeight::Name[fontDescription.weight] );
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                slant : [%s]\n\n", FontSlant::Name[fontDescription.slant] );
       }
     }
 
     FcFontSetDestroy( fontSet );
   }
+  DALI_LOG_INFO( gLogFilter, Debug::General, "<--FontClient::Plugin::InitSystemFonts\n" );
 }
 
-bool FontClient::Plugin::MatchFontDescriptionToPattern( FcPattern* pattern, Dali::TextAbstraction::FontDescription& fontDescription )
+bool FontClient::Plugin::MatchFontDescriptionToPattern( FcPattern* pattern, Dali::TextAbstraction::FontDescription& fontDescription, FcCharSet** characterSet )
 {
+  DALI_LOG_INFO( gLogFilter, Debug::General, "-->FontClient::Plugin::MatchFontDescriptionToPattern\n" );
+
   FcResult result = FcResultMatch;
   FcPattern* match = FcFontMatch( NULL /* use default configure */, pattern, &result );
 
-  bool ret = false;
+  const bool matched = NULL != match;
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  pattern matched : %s\n", ( matched ? "true" : "false" ) );
 
-  if( match )
+  if( matched )
   {
     int width = 0;
     int weight = 0;
     int slant = 0;
     GetFcString( match, FC_FILE, fontDescription.path );
     GetFcString( match, FC_FAMILY, fontDescription.family );
-    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "FontClient::Plugin::MatchFontDescriptionToPattern matched:%s \n", fontDescription.family.c_str());
     GetFcInt( match, FC_WIDTH, width );
     GetFcInt( match, FC_WEIGHT, weight );
     GetFcInt( match, FC_SLANT, slant );
@@ -1097,15 +1323,24 @@ bool FontClient::Plugin::MatchFontDescriptionToPattern( FcPattern* pattern, Dali
     fontDescription.weight = IntToWeightType( weight );
     fontDescription.slant = IntToSlantType( slant );
 
+    // Cache the character ranges.
+    FcPatternGetCharSet( match, FC_CHARSET, 0u, characterSet );
+
     // destroyed the matched pattern
     FcPatternDestroy( match );
-    ret = true;
+
+    DALI_LOG_INFO( gLogFilter, Debug::General, "  description; family : [%s]\n", fontDescription.family.c_str() );
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                 path : [%s]\n", fontDescription.path.c_str() );
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                width : [%s]\n", FontWidth::Name[fontDescription.width] );
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "               weight : [%s]\n", FontWeight::Name[fontDescription.weight] );
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                slant : [%s]\n\n", FontSlant::Name[fontDescription.slant] );
   }
-  return ret;
-}
 
+  DALI_LOG_INFO( gLogFilter, Debug::General, "<--FontClient::Plugin::MatchFontDescriptionToPattern\n" );
+  return matched;
+}
 
-FcPattern* FontClient::Plugin::CreateFontFamilyPattern( const FontDescription& fontDescription )
+FcPattern* FontClient::Plugin::CreateFontFamilyPattern( const FontDescription& fontDescription ) const
 {
   // create the cached font family lookup pattern
   // a pattern holds a set of names, each name refers to a property of the font
@@ -1223,11 +1458,14 @@ bool FontClient::Plugin::GetFcInt( const _FcPattern* const pattern, const char*
 
 FontId FontClient::Plugin::CreateFont( const FontPath& path,
                                        PointSize26Dot6 requestedPointSize,
-                                       PointSize26Dot6 actualPointSize,
                                        FaceIndex faceIndex,
                                        bool cacheDescription )
 {
-  FontId id( 0 );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "-->FontClient::Plugin::CreateFont\n" );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "                path : [%s]\n", path.c_str() );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  requestedPointSize : %d\n", requestedPointSize );
+
+  FontId id = 0u;
 
   // Create & cache new font face
   FT_Face ftFace;
@@ -1238,63 +1476,68 @@ FontId FontClient::Plugin::CreateFont( const FontPath& path,
 
   if( FT_Err_Ok == error )
   {
+    // Check if a font is scalable.
+    const bool isScalable = ( 0 != ( ftFace->face_flags & FT_FACE_FLAG_SCALABLE ) );
+    const bool hasFixedSizedBitmaps = ( 0 != ( ftFace->face_flags & FT_FACE_FLAG_FIXED_SIZES ) ) && ( 0 != ftFace->num_fixed_sizes );
+    const bool hasColorTables = ( 0 != ( ftFace->face_flags & FT_FACE_FLAG_COLOR ) );
+
+    DALI_LOG_INFO( gLogFilter, Debug::General, "            isScalable : [%s]\n", ( isScalable ? "true" : "false" ) );
+    DALI_LOG_INFO( gLogFilter, Debug::General, "  hasFixedSizedBitmaps : [%s]\n", ( hasFixedSizedBitmaps ? "true" : "false" ) );
+    DALI_LOG_INFO( gLogFilter, Debug::General, "        hasColorTables : [%s]\n", ( hasColorTables ? "true" : "false" ) );
+
     // Check to see if the font contains fixed sizes?
-    if ( ftFace->num_fixed_sizes && ftFace->available_sizes )
+    if( !isScalable && hasFixedSizedBitmaps )
     {
-      // Ensure this size is available
-      for ( int i = 0; i < ftFace->num_fixed_sizes; ++i )
+      PointSize26Dot6 actualPointSize = 0u;
+      int fixedSizeIndex = 0;
+      for( ; fixedSizeIndex < ftFace->num_fixed_sizes; ++fixedSizeIndex )
       {
-        if ( static_cast<FT_Pos>( actualPointSize ) == ftFace->available_sizes[ i ].size )
-        {
-          // Tell Freetype to use this size
-          error = FT_Select_Size( ftFace, i );
-          if ( FT_Err_Ok != error )
-          {
-            DALI_LOG_ERROR( "FreeType Select_Size error: %d\n", error );
-          }
-          else
-          {
-            float fixedWidth  = static_cast< float >( ftFace->available_sizes[ i ].width );
-            float fixedHeight = static_cast< float >( ftFace->available_sizes[ i ].height );
+        const PointSize26Dot6 fixedSize = ftFace->available_sizes[fixedSizeIndex].size;
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "  size index : %d, size : %d\n", fixedSizeIndex, fixedSize );
 
-            // Indicate that the font is a fixed sized bitmap
-            FontMetrics metrics( fixedHeight, // The ascender in pixels.
-                                 0.0f,
-                                 fixedHeight, // The height in pixels.
-                                 0.0f,
-                                 0.0f );
+        if( fixedSize >= requestedPointSize )
+        {
+          actualPointSize = fixedSize;
+          break;
+        }
+      }
 
-            mFontCache.push_back( FontFaceCacheItem( ftFace, path, requestedPointSize, faceIndex, metrics, fixedWidth, fixedHeight ) );
-            id = mFontCache.size();
+      if( 0u == actualPointSize )
+      {
+        // The requested point size is bigger than the bigest fixed size.
+        fixedSizeIndex = ftFace->num_fixed_sizes - 1;
+        actualPointSize = ftFace->available_sizes[fixedSizeIndex].size;
+      }
 
-            if( cacheDescription )
-            {
-              CacheFontPath( ftFace, id, requestedPointSize, path );
-            }
+      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "  size index : %d, actual size : %d\n", fixedSizeIndex, actualPointSize );
 
-            return id;
-          }
-        }
+      // Tell Freetype to use this size
+      error = FT_Select_Size( ftFace, fixedSizeIndex );
+      if ( FT_Err_Ok != error )
+      {
+        DALI_LOG_INFO( gLogFilter, Debug::General, "FreeType Select_Size error: %d\n", error );
       }
-
-      // Can't find this size
-      std::stringstream sizes;
-      for ( int i = 0; i < ftFace->num_fixed_sizes; ++i )
+      else
       {
-        if ( i )
-        {
-          sizes << ", ";
-        }
-        sizes << ftFace->available_sizes[ i ].size;
+        float fixedWidth  = static_cast< float >( ftFace->available_sizes[ fixedSizeIndex ].width );
+        float fixedHeight = static_cast< float >( ftFace->available_sizes[ fixedSizeIndex ].height );
+
+        // Indicate that the font is a fixed sized bitmap
+        FontMetrics metrics( fixedHeight, // The ascender in pixels.
+                             0.0f,
+                             fixedHeight, // The height in pixels.
+                             0.0f,
+                             0.0f );
+
+        mFontCache.push_back( FontFaceCacheItem( ftFace, path, requestedPointSize, faceIndex, metrics, fixedWidth, fixedHeight, hasColorTables ) );
+        id = mFontCache.size();
       }
-      DALI_LOG_ERROR( "FreeType Font: %s, does not contain Bitmaps of size: %d. Available sizes are: %s\n",
-                       path.c_str(), actualPointSize, sizes.str().c_str() );
     }
     else
     {
       error = FT_Set_Char_Size( ftFace,
                                 0,
-                                actualPointSize,
+                                requestedPointSize,
                                 mDpiHorizontal,
                                 mDpiVertical );
 
@@ -1311,23 +1554,29 @@ FontId FontClient::Plugin::CreateFont( const FontPath& path,
 
         mFontCache.push_back( FontFaceCacheItem( ftFace, path, requestedPointSize, faceIndex, metrics ) );
         id = mFontCache.size();
-
-        if( cacheDescription )
-        {
-          CacheFontPath( ftFace, id, requestedPointSize, path );
-        }
       }
       else
       {
-        DALI_LOG_ERROR( "FreeType Set_Char_Size error: %d for pointSize %d\n", error, actualPointSize );
+        DALI_LOG_INFO( gLogFilter, Debug::General, "  FreeType Set_Char_Size error: %d for pointSize %d\n", error, requestedPointSize );
+      }
+    }
+
+    if( 0u != id )
+    {
+      if( cacheDescription )
+      {
+        CacheFontPath( ftFace, id, requestedPointSize, path );
       }
     }
   }
   else
   {
-    DALI_LOG_ERROR( "FreeType New_Face error: %d for %s\n", error, path.c_str() );
+    DALI_LOG_INFO( gLogFilter, Debug::General, "  FreeType New_Face error: %d for [%s]\n", error, path.c_str() );
   }
 
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  font id : %d\n", id );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "<--FontClient::Plugin::CreateFont\n" );
+
   return id;
 }
 
@@ -1342,7 +1591,7 @@ void FontClient::Plugin::ConvertBitmap( TextAbstraction::FontClient::GlyphBuffer
         if( srcBitmap.pitch == static_cast<int>( srcBitmap.width ) )
         {
           const unsigned int bufferSize = srcBitmap.width * srcBitmap.rows;
-          data.buffer = new unsigned char[bufferSize];
+          data.buffer = new unsigned char[bufferSize]; // @note The caller is responsible for deallocating the bitmap data using delete[].
           data.width = srcBitmap.width;
           data.height = srcBitmap.rows;
           data.format = Pixel::L8;
@@ -1389,7 +1638,7 @@ void FontClient::Plugin::ConvertBitmap( TextAbstraction::FontClient::GlyphBuffer
 #endif
       default:
       {
-        DALI_LOG_ERROR( "FontClient Unable to create Bitmap of this PixelType\n" );
+        DALI_LOG_INFO( gLogFilter, Debug::General, "FontClient::Plugin::ConvertBitmap. FontClient Unable to create Bitmap of this PixelType\n" );
         break;
       }
     }
@@ -1401,6 +1650,11 @@ bool FontClient::Plugin::FindFont( const FontPath& path,
                                    FaceIndex faceIndex,
                                    FontId& fontId ) const
 {
+  DALI_LOG_INFO( gLogFilter, Debug::General, "-->FontClient::Plugin::FindFont\n" );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "                path : [%s]\n", path.c_str() );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  requestedPointSize : %d\n", requestedPointSize );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "  number of fonts in the cache : %d\n", mFontCache.size() );
+
   fontId = 0u;
   for( std::vector<FontFaceCacheItem>::const_iterator it = mFontCache.begin(),
          endIt = mFontCache.end();
@@ -1414,17 +1668,30 @@ bool FontClient::Plugin::FindFont( const FontPath& path,
         cacheItem.mPath == path )
     {
       ++fontId;
+
+      DALI_LOG_INFO( gLogFilter, Debug::General, "  font found, id : %d\n", fontId );
+      DALI_LOG_INFO( gLogFilter, Debug::General, "<--FontClient::Plugin::FindFont\n" );
+
       return true;
     }
   }
 
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  font not found\n" );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "<--FontClient::Plugin::FindFont\n" );
+
   return false;
 }
 
 bool FontClient::Plugin::FindValidatedFont( const FontDescription& fontDescription,
                                             FontDescriptionId& validatedFontId )
 {
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "FontClient::Plugin::FindValidatedFont fontDescription family(%s)\n", fontDescription.family.c_str() );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "-->FontClient::Plugin::FindValidatedFont\n" );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  description; family : [%s]\n", fontDescription.family.c_str() );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                 path : [%s]\n", fontDescription.path.c_str() );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                width : [%s]\n", FontWidth::Name[fontDescription.width] );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "               weight : [%s]\n", FontWeight::Name[fontDescription.weight] );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                slant : [%s]\n\n", FontSlant::Name[fontDescription.slant] );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "  number of validated fonts in the cache : %d\n", mValidatedFontCache.size() );
 
   validatedFontId = 0u;
 
@@ -1443,21 +1710,28 @@ bool FontClient::Plugin::FindValidatedFont( const FontDescription& fontDescripti
     {
       validatedFontId = item.index;
 
-      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "FontClient::Plugin::FindValidatedFont validated font family(%s) font id (%u) \n", fontDescription.family.c_str(), validatedFontId );
-
+      DALI_LOG_INFO( gLogFilter, Debug::General, "  validated font found, id : %d\n", validatedFontId );
+      DALI_LOG_INFO( gLogFilter, Debug::General, "<--FontClient::Plugin::FindValidatedFont\n" );
       return true;
     }
   }
 
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "FontClient::Plugin::FindValidatedFont NOT VALIDATED return false\n" );
-
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  validated font not found\n" );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "<--FontClient::Plugin::FindValidatedFont\n" );
   return false;
 }
 
 bool FontClient::Plugin::FindFallbackFontList( const FontDescription& fontDescription,
-                                               FontList*& fontList )
+                                               FontList*& fontList,
+                                               CharacterSetList*& characterSetList )
 {
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "FontClient::Plugin::FindFallbackFontList fontDescription family(%s)\n", fontDescription.family.c_str() );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "-->FontClient::Plugin::FindFallbackFontList\n" );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  description; family : [%s]\n", fontDescription.family.c_str() );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                 path : [%s]\n", fontDescription.path.c_str() );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                width : [%s]\n", FontWidth::Name[fontDescription.width] );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "               weight : [%s]\n", FontWeight::Name[fontDescription.weight] );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                slant : [%s]\n\n", FontSlant::Name[fontDescription.slant] );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "  number of fallback font lists in the cache : %d\n", mFallbackCache.size() );
 
   fontList = NULL;
 
@@ -1474,15 +1748,16 @@ bool FontClient::Plugin::FindFallbackFontList( const FontDescription& fontDescri
         ( fontDescription.slant == item.fontDescription.slant ) )
     {
       fontList = item.fallbackFonts;
+      characterSetList = item.characterSets;
 
-      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "FontClient::Plugin::FindFallbackFontList font family(%s) font-list (%p) \n", fontDescription.family.c_str(), fontList );
-
+      DALI_LOG_INFO( gLogFilter, Debug::General, "  fallback font list found.\n" );
+      DALI_LOG_INFO( gLogFilter, Debug::General, "<--FontClient::Plugin::FindFallbackFontList\n" );
       return true;
     }
   }
 
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "FontClient::Plugin::FindFallbackFontList NOT FOUND return false\n" );
-
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  fallback font list not found.\n" );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "<--FontClient::Plugin::FindFallbackFontList\n" );
   return false;
 }
 
@@ -1490,6 +1765,10 @@ bool FontClient::Plugin::FindFont( FontDescriptionId validatedFontId,
                                    PointSize26Dot6 requestedPointSize,
                                    FontId& fontId )
 {
+  DALI_LOG_INFO( gLogFilter, Debug::General, "-->FontClient::Plugin::FindFont\n" );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "    validatedFontId  : %d\n", validatedFontId );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  requestedPointSize : %d\n", requestedPointSize );
+
   fontId = 0u;
 
   for( std::vector<FontIdCacheItem>::const_iterator it = mFontIdCache.begin(),
@@ -1503,15 +1782,22 @@ bool FontClient::Plugin::FindFont( FontDescriptionId validatedFontId,
         ( requestedPointSize == item.requestedPointSize ) )
     {
       fontId = item.fontId;
+
+      DALI_LOG_INFO( gLogFilter, Debug::General, "  font found, id : %d\n", fontId );
+      DALI_LOG_INFO( gLogFilter, Debug::General, "<--FontClient::Plugin::FindFont\n" );
       return true;
     }
   }
 
+  DALI_LOG_INFO( gLogFilter, Debug::General, "  font not found.\n" );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "<--FontClient::Plugin::FindFont\n" );
   return false;
 }
 
 bool FontClient::Plugin::IsScalable( const FontPath& path )
 {
+  bool isScalable = false;
+
   FT_Face ftFace;
   int error = FT_New_Face( mFreeTypeLibrary,
                            path.c_str(),
@@ -1519,9 +1805,14 @@ bool FontClient::Plugin::IsScalable( const FontPath& path )
                            &ftFace );
   if( FT_Err_Ok != error )
   {
-    DALI_LOG_ERROR( "FreeType Cannot check font: %s\n", path.c_str() );
+    DALI_LOG_INFO( gLogFilter, Debug::General, "FontClient::Plugin::IsScalable. FreeType Cannot check font: %s\n", path.c_str() );
   }
-  return ( ftFace->num_fixed_sizes == 0 );
+  else
+  {
+    isScalable = ftFace->face_flags & FT_FACE_FLAG_SCALABLE;
+  }
+
+  return isScalable;
 }
 
 bool FontClient::Plugin::IsScalable( const FontDescription& fontDescription )
@@ -1533,7 +1824,7 @@ bool FontClient::Plugin::IsScalable( const FontDescription& fontDescription )
 
   // match the pattern
   FcPattern* match = FcFontMatch( NULL /* use default configure */, fontFamilyPattern, &result );
-  bool isScalable = true;
+  bool isScalable = false;
 
   if( match )
   {
@@ -1544,11 +1835,7 @@ bool FontClient::Plugin::IsScalable( const FontDescription& fontDescription )
   }
   else
   {
-    DALI_LOG_ERROR( "FreeType Cannot check font: %s %d %d %d\n",
-                    fontDescription.family.c_str(),
-                    fontDescription.width,
-                    fontDescription.weight,
-                    fontDescription.slant );
+    DALI_LOG_INFO( gLogFilter, Debug::General, "FontClient::Plugin::IsScalable. FreeType Cannot check font: [%s]\n", fontDescription.family.c_str() );
   }
   FcPatternDestroy( fontFamilyPattern );
   FcPatternDestroy( match );
@@ -1567,7 +1854,7 @@ void FontClient::Plugin::GetFixedSizes( const FontPath& path, Vector< PointSize2
                            &ftFace );
   if( FT_Err_Ok != error )
   {
-    DALI_LOG_ERROR( "FreeType Cannot check font: %s\n", path.c_str() );
+    DALI_LOG_INFO( gLogFilter, Debug::General, "FontClient::Plugin::GetFixedSizes. FreeType Cannot check font path : [%s]\n", path.c_str() );
   }
 
   // Fetch the number of fixed sizes available
@@ -1600,11 +1887,7 @@ void FontClient::Plugin::GetFixedSizes( const FontDescription& fontDescription,
   }
   else
   {
-    DALI_LOG_ERROR( "FreeType Cannot check font: %s %d %d %d\n",
-                    fontDescription.family.c_str(),
-                    fontDescription.width,
-                    fontDescription.weight,
-                    fontDescription.slant );
+    DALI_LOG_INFO( gLogFilter, Debug::General, "FontClient::Plugin::GetFixedSizes. FreeType Cannot check font: [%s]\n", fontDescription.family.c_str() );
   }
   FcPatternDestroy( match );
   FcPatternDestroy( fontFamilyPattern );
@@ -1636,8 +1919,22 @@ void FontClient::Plugin::CacheFontPath( FT_Face ftFace, FontId id, PointSize26Do
     // Set the index to the vector of paths to font file names.
     validatedFontId = mFontDescriptionCache.size();
 
+    FcPattern* pattern = CreateFontFamilyPattern( description );
+
+    FcResult result = FcResultMatch;
+    FcPattern* match = FcFontMatch( NULL, pattern, &result );
+
+    FcCharSet* characterSet = NULL;
+    FcPatternGetCharSet( match, FC_CHARSET, 0u, &characterSet );
+
+    FcPatternDestroy( match );
+    FcPatternDestroy( pattern );
+
+    mFontCache[id-1u].mCharacterSet = characterSet;
+
     // Add the path to the cache.
     mFontDescriptionCache.push_back( description );
+    mCharacterSetCache.PushBack( characterSet );
 
     // Cache the index and the font's description.
     FontDescriptionCacheItem item( description,
@@ -1652,6 +1949,26 @@ void FontClient::Plugin::CacheFontPath( FT_Face ftFace, FontId id, PointSize26Do
   }
 }
 
+FcCharSet* FontClient::Plugin::CreateCharacterSetFromDescription( const FontDescription& description ) const
+{
+  FcCharSet* characterSet = NULL;
+
+  FcPattern* pattern = CreateFontFamilyPattern( description );
+
+  if( NULL != pattern )
+  {
+    FcResult result = FcResultMatch;
+    FcPattern* match = FcFontMatch( NULL, pattern, &result );
+
+    FcPatternGetCharSet( match, FC_CHARSET, 0u, &characterSet );
+
+    FcPatternDestroy( match );
+    FcPatternDestroy( pattern );
+  }
+
+  return characterSet;
+}
+
 } // namespace Internal
 
 } // namespace TextAbstraction
index fcd7953..d0601e7 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_INTERNAL_TEXT_ABSTRACTION_FONT_CLIENT_PLUGIN_IMPL_H__
-#define __DALI_INTERNAL_TEXT_ABSTRACTION_FONT_CLIENT_PLUGIN_IMPL_H__
+#ifndef DALI_INTERNAL_TEXT_ABSTRACTION_FONT_CLIENT_PLUGIN_IMPL_H
+#define DALI_INTERNAL_TEXT_ABSTRACTION_FONT_CLIENT_PLUGIN_IMPL_H
 
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -35,6 +35,7 @@ class VectorFontCache;
 #include FT_GLYPH_H
 
 // forward declarations of font config types.
+struct _FcCharSet;
 struct _FcFontSet;
 struct _FcPattern;
 
@@ -51,6 +52,7 @@ namespace Internal
  *@brief Type used for indices addressing the vector with front descriptions of validated fonts.
  */
 typedef uint32_t FontDescriptionId;
+typedef Vector<_FcCharSet*> CharacterSetList;
 
 /**
  * @brief FontClient implementation.
@@ -62,10 +64,11 @@ struct FontClient::Plugin
    */
   struct FallbackCacheItem
   {
-    FallbackCacheItem( const FontDescription& fontDescription, FontList* fallbackFonts );
+    FallbackCacheItem( const FontDescription& fontDescription, FontList* fallbackFonts, CharacterSetList* characterSets );
 
     FontDescription fontDescription; ///< The font description.
     FontList* fallbackFonts;         ///< The list of fallback fonts for the given font-description.
+    CharacterSetList* characterSets; ///< The list of character sets for the given font-description.
   };
 
   /**
@@ -111,17 +114,20 @@ struct FontClient::Plugin
                        FaceIndex face,
                        const FontMetrics& metrics,
                        float fixedWidth,
-                       float fixedHeight );
+                       float fixedHeight,
+                       bool hasColorTables );
 
     FT_Face mFreeTypeFace;               ///< The FreeType face.
     FontPath mPath;                      ///< The path to the font file name.
     PointSize26Dot6 mRequestedPointSize; ///< The font point size.
     FaceIndex mFaceIndex;                ///< The face index.
     FontMetrics mMetrics;                ///< The font metrics.
+    _FcCharSet* mCharacterSet;           ///< Pointer with the range of characters.
     FT_Short mFixedWidthPixels;          ///< The height in pixels (fixed size bitmaps only)
     FT_Short mFixedHeightPixels;         ///< The height in pixels (fixed size bitmaps only)
     unsigned int mVectorFontId;          ///< The ID of the equivalent vector-based font
-    bool mIsFixedSizeBitmap;             ///< Whether the font has fixed size bitmaps.
+    bool mIsFixedSizeBitmap : 1;         ///< Whether the font has fixed size bitmaps.
+    bool mHasColorTables    : 1;         ///< Whether the font has color tables.
   };
 
   struct EllipsisItem
@@ -189,9 +195,15 @@ struct FontClient::Plugin
   PointSize26Dot6 GetPointSize( FontId id );
 
   /**
+   * @copydoc Dali::TextAbstraction::FontClient::IsCharacterSupportedByFont()
+   */
+  bool IsCharacterSupportedByFont( FontId fontId, Character character );
+
+  /**
    * @brief Finds within the @p fontList a font which support the @p carcode.
    *
    * @param[in] fontList A list of font paths, family, width, weight and slant.
+   * @param[in] characterSetList A list that contains a character set for each description of the font list.
    * @param[in] charcode The character for which a font is needed.
    * @param[in] requestedPointSize The point size in 26.6 fractional points.
    * @param[in] preferColor @e true if a color font is preferred.
@@ -199,6 +211,7 @@ struct FontClient::Plugin
    * @return A valid font identifier, or zero if no font is found.
    */
   FontId FindFontForCharacter( const FontList& fontList,
+                               const CharacterSetList& characterSetList,
                                Character charcode,
                                PointSize26Dot6 requestedPointSize,
                                bool preferColor );
@@ -221,23 +234,18 @@ struct FontClient::Plugin
   /**
    * @see Dali::TextAbstraction::FontClient::GetFontId( const FontPath& path, PointSize26Dot6 requestedPointSize, FaceIndex faceIndex )
    *
-   * @param[in] actualPointSize The actual point size. In case of emojis the @p requestedPointSize is used to build the metrics and cache the font and the @p actualPointSize is used to load the glyph.
    * @param[in] cacheDescription Whether to cache the font description.
    */
   FontId GetFontId( const FontPath& path,
                     PointSize26Dot6 requestedPointSize,
-                    PointSize26Dot6 actualPointSize,
                     FaceIndex faceIndex,
-                    bool cacheDescription = true );
+                    bool cacheDescription );
 
   /**
-   * @see Dali::TextAbstraction::FontClient::GetFontId( const FontDescription& preferredFontDescription, PointSize26Dot6 requestedPointSize, FaceIndex faceIndex )
-   *
-   * @param[in] actualPointSize The actual point size. In case of emojis the @p requestedPointSize is used to build the metrics and cache the font and the @p actualPointSize is used to load the glyph.
+   * @copydoc Dali::TextAbstraction::FontClient::GetFontId( const FontDescription& preferredFontDescription, PointSize26Dot6 requestedPointSize, FaceIndex faceIndex )
    */
   FontId GetFontId( const FontDescription& fontDescription,
                     PointSize26Dot6 requestedPointSize,
-                    PointSize26Dot6 actualPointSize,
                     FaceIndex faceIndex );
 
   /**
@@ -321,12 +329,13 @@ private:
   void InitSystemFonts();
 
   /**
-   * @brief Gets the FontDescription which matches the given pattern
-   * @param[in] pattern pattern to match against
-   * @param[out] fontDescription the resultant fontDescription that matched
-   * @return true if match found
+   * @brief Gets the FontDescription which matches the given pattern.
+   * @param[in] pattern pattern to match against.
+   * @param[out] fontDescription the resultant fontDescription that matched.
+   * @param[out] characterSet The character set for that pattern.
+   * @return true if match found.
    */
-  bool MatchFontDescriptionToPattern( _FcPattern* pattern, Dali::TextAbstraction::FontDescription& fontDescription );
+  bool MatchFontDescriptionToPattern( _FcPattern* pattern, Dali::TextAbstraction::FontDescription& fontDescription, _FcCharSet** characterSet );
 
   /**
    * @brief Creates a font family pattern used to match fonts.
@@ -335,7 +344,7 @@ private:
    *
    * @return The pattern.
    */
-  _FcPattern* CreateFontFamilyPattern( const FontDescription& fontDescription );
+  _FcPattern* CreateFontFamilyPattern( const FontDescription& fontDescription ) const;
 
   /**
    * Retrieves the fonts present in the platform.
@@ -371,7 +380,6 @@ private:
    *
    * @param[in] path The path to the font file name.
    * @param[in] requestedPointSize The requested point size.
-   * @param[in] actualPointSize The actual point size (for color emojis).
    * @param[in] faceIndex A face index.
    * @param[in] cacheDescription Whether to cache the font description.
    *
@@ -379,7 +387,6 @@ private:
    */
   FontId CreateFont( const FontPath& path,
                      PointSize26Dot6 requestedPointSize,
-                     PointSize26Dot6 actualPointSize,
                      FaceIndex faceIndex,
                      bool cacheDescription );
 
@@ -421,9 +428,11 @@ private:
    *
    * @param[in] fontDescription The font to validate.
    * @param[out] A valid pointer to a font list, or NULL if not found.
+   * @param[out] characterSetList A valid pointer to a character set list, or NULL if not found.
    */
   bool FindFallbackFontList( const FontDescription& fontDescription,
-                             FontList*& fontList );
+                             FontList*& fontList,
+                             CharacterSetList*& characterSetList );
 
   /**
    * @brief Finds in the cache a pair 'validated font identifier and font point size'.
@@ -453,8 +462,9 @@ private:
    *
    * @param[in] fontDescription A font description.
    * @param[out] fontList A list of the fonts which are a close match for fontDescription.
+   * @param[out] characterSetList A list of the character sets which are a close match for fontDescription.
    */
-  void SetFontList( const FontDescription& fontDescription, FontList& fontList );
+  void SetFontList( const FontDescription& fontDescription, FontList& fontList, CharacterSetList& characterSetList );
 
   /**
    * Caches a font path.
@@ -466,6 +476,15 @@ private:
    */
   void CacheFontPath( FT_Face ftFace, FontId id, PointSize26Dot6 requestedPointSize,  const FontPath& path );
 
+  /**
+   * @brief Creates a character set from a given font's @p description.
+   *
+   * @param[in] description The font's description.
+   *
+   * @return A character set.
+   */
+  _FcCharSet* CreateCharacterSetFromDescription( const FontDescription& description ) const;
+
 private:
 
   // Declared private and left undefined to avoid copies.
@@ -484,12 +503,14 @@ private:
 
   FontList mSystemFonts;       ///< Cached system fonts.
   FontList mDefaultFonts;      ///< Cached default fonts.
+  CharacterSetList mDefaultFontCharacterSets;
 
   std::vector<FallbackCacheItem> mFallbackCache; ///< Cached fallback font lists.
 
   std::vector<FontFaceCacheItem>        mFontCache;            ///< Caches the FreeType face and font metrics of the triplet 'path to the font file name, font point size and face index'.
   std::vector<FontDescriptionCacheItem> mValidatedFontCache;   ///< Caches indices to the vector of font descriptions for a given font.
   FontList                              mFontDescriptionCache; ///< Caches font descriptions for the validated font.
+  CharacterSetList                      mCharacterSetCache;    ///< Caches character set lists for the validated font.
   std::vector<FontIdCacheItem>          mFontIdCache;          ///< Caches font identifiers for the pairs of font point size and the index to the vector with font descriptions of the validated fonts.
 
   VectorFontCache* mVectorFontCache; ///< Separate cache for vector data blobs etc.
@@ -505,4 +526,4 @@ private:
 
 } // namespace Dali
 
-#endif // __DALI_INTERNAL_TEXT_ABSTRACTION_FONT_CLIENT_PLUGIN_IMPL_H__
+#endif // DALI_INTERNAL_TEXT_ABSTRACTION_FONT_CLIENT_PLUGIN_IMPL_H