FontClient - Fix issues when selecting fonts. 90/82790/1
authorVictor Cebollada <v.cebollada@samsung.com>
Wed, 3 Aug 2016 15:01:01 +0000 (16:01 +0100)
committerVictor Cebollada <v.cebollada@samsung.com>
Fri, 5 Aug 2016 16:02:43 +0000 (17:02 +0100)
* Uses the preferred font's description instead the preferred
  font's identifier to find a fall-back font.
* Added a NONE value in the FontWidth, FontWeight and FontSlant
  enum types to state that no style has been defined by the user.

Change-Id: I19579d8f19ab79d813c05c65458a094ac0ae87f6
Signed-off-by: Victor Cebollada <v.cebollada@samsung.com>
automated-tests/src/dali-adaptor-internal/utc-Dali-FontClient.cpp
text/dali/devel-api/text-abstraction/font-client.cpp
text/dali/devel-api/text-abstraction/font-client.h
text/dali/devel-api/text-abstraction/font-list.h
text/dali/internal/text-abstraction/font-client-helper.cpp
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 fdb1df5..0134b9b 100644 (file)
@@ -27,40 +27,61 @@ using namespace Dali;
 
 int UtcDaliFontClient(void)
 {
-  const int ORDERED_VALUES[] = { 50, 63, 75, 87, 100, 113, 125, 150, 200 };
+  const int ORDERED_VALUES[] = { -1, 50, 63, 75, 87, 100, 113, 125, 150, 200 };
 
   const unsigned int NUM_OF_ORDERED_VALUES = sizeof( ORDERED_VALUES ) / sizeof( int );
 
   TestApplication application;
-  int preciseIndex = 0;
   int result=0;
 
-  tet_infoline("UtcDaliFontClient center range");
-  preciseIndex = 4;
-  result = TextAbstraction::Internal::ValueToIndex( ORDERED_VALUES[preciseIndex], ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u );
-  DALI_TEST_EQUALS( preciseIndex, result, TEST_LOCATION );
+  tet_infoline("UtcDaliFontClient No table");
+  result = TextAbstraction::Internal::ValueToIndex( 100, NULL, 0u );
+  DALI_TEST_EQUALS( -1, result, TEST_LOCATION );
 
-  tet_infoline("UtcDaliFontClient start of range");
-  preciseIndex = 0;
-  result = TextAbstraction::Internal::ValueToIndex( ORDERED_VALUES[preciseIndex], ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u );
-  DALI_TEST_EQUALS( preciseIndex, result, TEST_LOCATION );
-
-  tet_infoline("UtcDaliFontClient end of range");
-  preciseIndex = 8;
-  result = TextAbstraction::Internal::ValueToIndex( ORDERED_VALUES[preciseIndex], ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u );
-  DALI_TEST_EQUALS( preciseIndex, result, TEST_LOCATION );
+  tet_infoline("UtcDaliFontClient Non defined values");
+  result = TextAbstraction::Internal::ValueToIndex( -1, ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u );
+  DALI_TEST_EQUALS( 0, result, TEST_LOCATION );
+  result = TextAbstraction::Internal::ValueToIndex( -3, ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u );
+  DALI_TEST_EQUALS( 0, result, TEST_LOCATION );
 
-  tet_infoline("UtcDaliFontClient below of range");
+  tet_infoline("UtcDaliFontClient Between non defined and first of range.");
+  result = TextAbstraction::Internal::ValueToIndex( 0, ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u );
+  DALI_TEST_EQUALS( 1, result, TEST_LOCATION );
   result = TextAbstraction::Internal::ValueToIndex( 30, ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u );
-  DALI_TEST_EQUALS( 0, result, TEST_LOCATION );
+  DALI_TEST_EQUALS( 1, result, TEST_LOCATION );
+  result = TextAbstraction::Internal::ValueToIndex( 49, ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u );
+  DALI_TEST_EQUALS( 1, result, TEST_LOCATION );
 
-  tet_infoline("UtcDaliFontClient below of range");
-  result = TextAbstraction::Internal::ValueToIndex( 220, ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u );
+  tet_infoline("UtcDaliFontClient Defined in range");
+  for( unsigned int index = 1u; index < NUM_OF_ORDERED_VALUES; ++index )
+  {
+    result = TextAbstraction::Internal::ValueToIndex( ORDERED_VALUES[index], ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u );
+    DALI_TEST_EQUALS( index, result, TEST_LOCATION );
+  }
+
+  tet_infoline("UtcDaliFontClient Non defined in range");
+  result = TextAbstraction::Internal::ValueToIndex( 51, ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u );
+  DALI_TEST_EQUALS( 1, result, TEST_LOCATION );
+  result = TextAbstraction::Internal::ValueToIndex( 55, ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u );
+  DALI_TEST_EQUALS( 1, result, TEST_LOCATION );
+  result = TextAbstraction::Internal::ValueToIndex( 62, ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u );
+  DALI_TEST_EQUALS( 2, result, TEST_LOCATION );
+  result = TextAbstraction::Internal::ValueToIndex( 64, ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u );
+  DALI_TEST_EQUALS( 2, result, TEST_LOCATION );
+  result = TextAbstraction::Internal::ValueToIndex( 151, ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u );
   DALI_TEST_EQUALS( 8, result, TEST_LOCATION );
+  result = TextAbstraction::Internal::ValueToIndex( 175, ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u );
+  DALI_TEST_EQUALS( 9, result, TEST_LOCATION );
+  result = TextAbstraction::Internal::ValueToIndex( 176, ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u );
+  DALI_TEST_EQUALS( 9, result, TEST_LOCATION );
+  result = TextAbstraction::Internal::ValueToIndex( 199, ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u );
+  DALI_TEST_EQUALS( 9, result, TEST_LOCATION );
 
-  tet_infoline("UtcDaliFontClient zero ");
-  result = TextAbstraction::Internal::ValueToIndex( 0, ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u );
-  DALI_TEST_EQUALS( 0, result, TEST_LOCATION );
+  tet_infoline("UtcDaliFontClient above of range");
+  result = TextAbstraction::Internal::ValueToIndex( 220, ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u );
+  DALI_TEST_EQUALS( 9, result, TEST_LOCATION );
+  result = TextAbstraction::Internal::ValueToIndex( 500, ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u );
+  DALI_TEST_EQUALS( 9, result, TEST_LOCATION );
 
   END_TEST;
 }
index 048a6f2..e8fba7f 100644 (file)
@@ -93,14 +93,21 @@ PointSize26Dot6 FontClient::GetPointSize( FontId id )
   return GetImplementation(*this).GetPointSize( id );
 }
 
-FontId FontClient::FindDefaultFont( Character charcode, PointSize26Dot6 requestedPointSize, bool preferColor )
+FontId FontClient::FindDefaultFont( Character charcode,
+                                    PointSize26Dot6 requestedPointSize,
+                                    bool preferColor )
 {
-  return GetImplementation(*this).FindDefaultFont( charcode, requestedPointSize, preferColor );
+  return GetImplementation(*this).FindDefaultFont( charcode,
+                                                   requestedPointSize,
+                                                   preferColor );
 }
 
-FontId FontClient::FindFallbackFont( FontId preferredFont, Character charcode, PointSize26Dot6 requestedPointSize, bool preferColor )
+FontId FontClient::FindFallbackFont( Character charcode,
+                                     const FontDescription& preferredFontDescription,
+                                     PointSize26Dot6 requestedPointSize,
+                                     bool preferColor )
 {
-  return GetImplementation(*this).FindFallbackFont( preferredFont, charcode, requestedPointSize, preferColor );
+  return GetImplementation(*this).FindFallbackFont( charcode, preferredFontDescription, requestedPointSize, preferColor );
 }
 
 FontId FontClient::GetFontId( const FontPath& path, PointSize26Dot6 requestedPointSize, FaceIndex faceIndex )
index 326622c..885fe6c 100644 (file)
@@ -132,36 +132,36 @@ public:
   /**
    * @brief Retrieve the list of default fonts supported by the system.
    *
-   * @param[out] defaultFonts A list of default font paths, family & style strings.
+   * @param[out] defaultFonts A list of default font paths, family, width, weight and slant.
    */
   void GetDefaultFonts( FontList& defaultFonts );
 
   /**
-   * @brief Retrieve the active default font from the system
+   * @brief Retrieve the active default font from the system.
    *
-   * @param[out] fontDescription font structure describing the default font
+   * @param[out] fontDescription font structure describing the default font.
    */
   void GetDefaultPlatformFontDescription( FontDescription& fontDescription );
 
   /**
    * @brief Retrieve the list of fonts supported by the system.
    *
-   * @param[out] systemFonts A list of font paths, family & style strings.
+   * @param[out] systemFonts A list of font paths, family, width, weight and slant.
    */
   void GetSystemFonts( FontList& systemFonts );
 
   /**
    * @brief Retrieves the font description of a given font @p id.
    *
-   * @param[in] id The font id.
-   * @param[out] fontDescription The path, family & style describing the font.
+   * @param[in] id The font identifier.
+   * @param[out] fontDescription The path, family & style (width, weight and slant) describing the font.
    */
   void GetDescription( FontId id, FontDescription& fontDescription );
 
   /**
    * @brief Retrieves the font point size of a given font @p id.
    *
-   * @param[in] id The font id.
+   * @param[in] id The font identifier.
    *
    * @return The point size in 26.6 fractional points.
    */
@@ -172,10 +172,12 @@ public:
    *
    * This is useful when localised strings are provided for multiple languages
    * i.e. when a single default font does not work for all languages.
+   *
    * @param[in] charcode The character for which a font is needed.
    * @param[in] requestedPointSize The point size in 26.6 fractional points; the default point size is 12*64.
-   * @param[in] preferColor True if a color font is preferred.
-   * @return A valid font ID, or zero if the font does not exist.
+   * @param[in] preferColor @e true if a color font is preferred.
+   *
+   * @return A valid font identifier, or zero if the font does not exist.
    */
   FontId FindDefaultFont( Character charcode,
                           PointSize26Dot6 requestedPointSize = DEFAULT_POINT_SIZE,
@@ -186,15 +188,17 @@ public:
    *
    * This is useful when localised strings are provided for multiple languages
    * i.e. when a single default font does not work for all languages.
-   * @param[in] preferredFont The preferred font which may not provide a glyph for charcode.
-   * The fallback-font will be the closest match to preferredFont, which does support the required glyph.
+   *
    * @param[in] charcode The character for which a font is needed.
+   * @param[in] preferredFontDescription Description of the preferred font which may not provide a glyph for @p charcode.
+   *                                     The fallback-font will be the closest match to @p preferredFontDescription, which does support the required glyph.
    * @param[in] requestedPointSize The point size in 26.6 fractional points; the default point size is 12*64.
-   * @param[in] preferColor True if a color font is preferred.
-   * @return A valid font ID, or zero if the font does not exist.
+   * @param[in] preferColor @e true if a color font is preferred.
+   *
+   * @return A valid font identifier, or zero if the font does not exist.
    */
-  FontId FindFallbackFont( FontId preferredFont,
-                           Character charcode,
+  FontId FindFallbackFont( Character charcode,
+                           const FontDescription& preferredFontDescription,
                            PointSize26Dot6 requestedPointSize = DEFAULT_POINT_SIZE,
                            bool preferColor = false );
 
@@ -204,23 +208,24 @@ public:
    * @param[in] path The path to a font file.
    * @param[in] requestedPointSize The point size in 26.6 fractional points; the default point size is 12*64.
    * @param[in] faceIndex The index of the font face (optional).
-   * @return A valid font ID, or zero if the font does not exist.
+   *
+   * @return A valid font identifier, or zero if the font does not exist.
    */
   FontId GetFontId( const FontPath& path,
                     PointSize26Dot6 requestedPointSize = DEFAULT_POINT_SIZE,
                     FaceIndex faceIndex = 0 );
 
   /**
-   * @brief Retrieve the unique identifier for a font.
+   * @brief Retrieves a unique font identifier for a given description.
    *
-   * @note It the font style is not empty, it will be used instead the font weight and font slant slant.
-   *
-   * @param[in] fontDescription A font description.
+   * @param[in] preferredFontDescription Description of the preferred font.
+   *                                     The font will be the closest match to @p preferredFontDescription.
    * @param[in] requestedPointSize The point size in 26.6 fractional points; the default point size is 12*64.
    * @param[in] faceIndex The index of the font face (optional).
-   * @return A valid font ID, or zero if the font does not exist.
+   *
+   * @return A valid font identifier, or zero if no font is found.
    */
-  FontId GetFontId( const FontDescription& fontDescription,
+  FontId GetFontId( const FontDescription& preferredFontDescription,
                     PointSize26Dot6 requestedPointSize = DEFAULT_POINT_SIZE,
                     FaceIndex faceIndex = 0 );
 
@@ -269,7 +274,7 @@ public:
   /**
    * @brief Query the metrics for a font.
    *
-   * @param[in] fontId The ID of the font for the required glyph.
+   * @param[in] fontId The identifier of the font for the required glyph.
    * @param[out] metrics The font metrics.
    */
   void GetFontMetrics( FontId fontId, FontMetrics& metrics );
@@ -277,8 +282,9 @@ public:
   /**
    * @brief Retrieve the glyph index for a UTF-32 character code.
    *
-   * @param[in] fontId The ID of the font for the required glyph.
+   * @param[in] fontId The identifier of the font for the required glyph.
    * @param[in] charcode The UTF-32 character code.
+   *
    * @return The glyph index, or zero if the character code is undefined.
    */
   GlyphIndex GetGlyphIndex( FontId fontId, Character charcode );
@@ -287,20 +293,22 @@ public:
    * @brief Retrieve the metrics for a series of glyphs.
    *
    * @param[in,out] array An array of glyph-info structures with initialized FontId & GlyphIndex values.
-   * It may contain the advance and an offset set into the bearing from the shaping tool.
-   * On return, the glyph's size value will be initialized. The bearing value will be updated by adding the font's glyph bearing to the one set by the shaping tool.
+   *                      It may contain the advance and an offset set into the bearing from the shaping tool.
+   *                      On return, the glyph's size value will be initialized. The bearing value will be updated by adding the font's glyph bearing to the one set by the shaping tool.
    * @param[in] size The size of the array.
    * @param[in] type The type of glyphs used for rendering; either bitmaps or vectors.
    * @param[in] horizontal True for horizontal layouts (set to false for vertical layouting).
-   * @return True if all of the requested metrics were found.
+   *
+   * @return @e true if all of the requested metrics were found.
    */
   bool GetGlyphMetrics( GlyphInfo* array, uint32_t size, GlyphType type, bool horizontal = true );
 
   /**
    * @brief Create a bitmap representation of a glyph.
    *
-   * @param[in] fontId The ID of the font.
+   * @param[in] fontId The identifier of the font.
    * @param[in] glyphIndex The index of a glyph within the specified font.
+   *
    * @return A valid BufferImage, or an empty handle if the glyph could not be rendered.
    */
   PixelData CreateBitmap( FontId fontId, GlyphIndex glyphIndex );
@@ -309,7 +317,7 @@ public:
    * @brief Create a vector representation of a glyph.
    *
    * @note This feature requires highp shader support and is not available on all platforms
-   * @param[in] fontId The ID of the font.
+   * @param[in] fontId The identifier of the font.
    * @param[in] glyphIndex The index of a glyph within the specified font.
    * @param[out] blob A blob of data; this is owned by FontClient and should be copied by the caller of CreateVectorData().
    * @param[out] blobLength The length of the blob data, or zero if the blob creation failed.
index 46e2438..9170941 100644 (file)
@@ -39,6 +39,7 @@ namespace FontWidth
    */
   enum Type
   {
+    NONE,            ///< Means not defined. Will use what is set as default, currently NORMAL.
     ULTRA_CONDENSED,
     EXTRA_CONDENSED,
     CONDENSED,
@@ -47,7 +48,21 @@ namespace FontWidth
     SEMI_EXPANDED,
     EXPANDED,
     EXTRA_EXPANDED,
-    ULTRA_EXPANDED,
+    ULTRA_EXPANDED
+  };
+
+  const char* const Name[] =
+  {
+    "NONE",
+    "ULTRA_CONDENSED",
+    "EXTRA_CONDENSED",
+    "CONDENSED",
+    "SEMI_CONDENSED",
+    "NORMAL",
+    "SEMI_EXPANDED",
+    "EXPANDED",
+    "EXTRA_EXPANDED",
+    "ULTRA_EXPANDED"
   };
 } // namespace FontWidth
 
@@ -58,6 +73,7 @@ namespace FontWeight
    */
   enum Type
   {
+    NONE,                      ///< Means not defined. Will use what is set as default, currently NORMAL.
     THIN,
     ULTRA_LIGHT,
     EXTRA_LIGHT = ULTRA_LIGHT,
@@ -77,6 +93,22 @@ namespace FontWeight
     HEAVY = BLACK,
     EXTRA_BLACK = BLACK
   };
+
+  const char* const Name[] =
+  {
+    "NONE",
+    "THIN",
+    "ULTRA_LIGHT",
+    "LIGHT",
+    "DEMI_LIGHT",
+    "BOOK",
+    "NORMAL",
+    "MEDIUM",
+    "DEMI_BOLD",
+    "BOLD",
+    "ULTRA_BOLD",
+    "BLACK"
+  };
 }
 
 namespace FontSlant
@@ -86,11 +118,20 @@ namespace FontSlant
    */
   enum Type
   {
+    NONE,           ///< Means not defined. Will use what is set as default, currently NORMAL.
     NORMAL,
     ROMAN = NORMAL,
     ITALIC,
     OBLIQUE
   };
+
+  const char* const Name[] =
+  {
+    "NONE",
+    "NORMAL",
+    "ITALIC",
+    "OBLIQUE"
+  };
 } // namespace FontSlant
 
 struct FontDescription
@@ -98,9 +139,9 @@ struct FontDescription
   FontDescription()
   : path(),
     family(),
-    width( FontWidth::NORMAL ),
-    weight( FontWeight::NORMAL ),
-    slant( FontSlant::NORMAL )
+    width( FontWidth::NONE ),
+    weight( FontWeight::NONE ),
+    slant( FontSlant::NONE )
   {}
 
   ~FontDescription()
index d7e3e16..d84e4de 100644 (file)
@@ -42,8 +42,13 @@ int ValueToIndex( int value, const int* const table, unsigned int maxIndex )
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "-->FontClient::Plugin::ValueToIndex value(%d)\n", value);
 
-  if( ( NULL == table ) ||
-      ( value <= table[0] ) )
+  if( NULL == table )
+  {
+    // Return an invalid index if there is no table.
+    return -1;
+  }
+
+  if( value <= table[0] )
   {
     return 0;
   }
@@ -53,14 +58,14 @@ int ValueToIndex( int value, const int* const table, unsigned int maxIndex )
     return maxIndex;
   }
 
-  for( unsigned int index = 0u; index < maxIndex; )
+  for( unsigned int index = 0u; index < maxIndex; ++index )
   {
     const int v1 = table[index];
-    const unsigned int indexPlus = ++index;
+    const unsigned int indexPlus = index + 1u;
     const int v2 = table[indexPlus];
     if( ( v1 < value ) && ( value <= v2 ) )
     {
-      const int result = ( ( value - v1 ) < ( v2 - value ) ) ? index : indexPlus;
+      const int result = ( ( v1 > 0 ) && ( ( value - v1 ) < ( v2 - value ) ) ) ? index : indexPlus;
       DALI_LOG_INFO( gLogFilter, Debug::Verbose, "FontClient::Plugin::ValueToIndex result(%d)\n",  result );
       return result;
     }
index 42a2a8a..040c557 100644 (file)
@@ -128,18 +128,28 @@ void FontClient::GetSystemFonts( FontList& systemFonts )
   mPlugin->GetSystemFonts( systemFonts );
 }
 
-FontId FontClient::FindDefaultFont( Character charcode, PointSize26Dot6 requestedPointSize, bool preferColor )
+FontId FontClient::FindDefaultFont( Character charcode,
+                                    PointSize26Dot6 requestedPointSize,
+                                    bool preferColor )
 {
   CreatePlugin();
 
-  return mPlugin->FindDefaultFont( charcode, requestedPointSize, preferColor );
+  return mPlugin->FindDefaultFont( charcode,
+                                   requestedPointSize,
+                                   preferColor );
 }
 
-FontId FontClient::FindFallbackFont( FontId preferredFont, Character charcode, PointSize26Dot6 requestedPointSize, bool preferColor )
+FontId FontClient::FindFallbackFont( Character charcode,
+                                     const FontDescription& preferredFontDescription,
+                                     PointSize26Dot6 requestedPointSize,
+                                     bool preferColor )
 {
   CreatePlugin();
 
-  return mPlugin->FindFallbackFont( preferredFont, charcode, requestedPointSize, preferColor );
+  return mPlugin->FindFallbackFont( charcode,
+                                    preferredFontDescription,
+                                    requestedPointSize,
+                                    preferColor );
 }
 
 bool FontClient::IsScalable( const FontPath& path )
index 783147c..555fca8 100644 (file)
@@ -98,12 +98,17 @@ public:
   /**
    * @copydoc Dali::FontClient::FindDefaultFont()
    */
-  FontId FindDefaultFont( Character charcode, PointSize26Dot6 requestedPointSize, bool preferColor );
+  FontId FindDefaultFont( Character charcode,
+                          PointSize26Dot6 requestedPointSize,
+                          bool preferColor );
 
   /**
    * @copydoc Dali::FontClient::FindFallbackFont()
    */
-  FontId FindFallbackFont( FontId preferredFont, Character charcode, PointSize26Dot6 requestedPointSize, bool preferColor );
+  FontId FindFallbackFont( Character charcode,
+                           const FontDescription& preferredFontDescription,
+                           PointSize26Dot6 requestedPointSize,
+                           bool preferColor );
 
   /**
    * @copydoc Dali::FontClient::GetFontId( const FontPath& path, PointSize26Dot6 requestedPointSize, FaceIndex faceIndex )
index feaec05..56e297c 100644 (file)
@@ -55,6 +55,7 @@ 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.
 // ULTRA_CONDENSED 50
 // EXTRA_CONDENSED 63
 // CONDENSED       75
@@ -64,9 +65,10 @@ const bool FONT_FIXED_SIZE_BITMAP( true );
 // EXPANDED       125
 // EXTRA_EXPANDED 150
 // ULTRA_EXPANDED 200
-const int FONT_WIDTH_TYPE_TO_INT[] = { 50, 63, 75, 87, 100, 113, 125, 150, 200 };
+const int FONT_WIDTH_TYPE_TO_INT[] = { -1, 50, 63, 75, 87, 100, 113, 125, 150, 200 };
 const unsigned int NUM_FONT_WIDTH_TYPE = sizeof( FONT_WIDTH_TYPE_TO_INT ) / sizeof( int );
 
+// NONE                       -1  --> DEFAULT_FONT_WEIGHT (NORMAL) will be used.
 // THIN                        0
 // ULTRA_LIGHT, EXTRA_LIGHT   40
 // LIGHT                      50
@@ -78,13 +80,14 @@ const unsigned int NUM_FONT_WIDTH_TYPE = sizeof( FONT_WIDTH_TYPE_TO_INT ) / size
 // BOLD                      200
 // ULTRA_BOLD, EXTRA_BOLD    205
 // BLACK, HEAVY, EXTRA_BLACK 210
-const int FONT_WEIGHT_TYPE_TO_INT[] = { 0, 40, 50, 55, 75, 80, 100, 180, 200, 205, 210 };
+const int FONT_WEIGHT_TYPE_TO_INT[] = { -1, 0, 40, 50, 55, 75, 80, 100, 180, 200, 205, 210 };
 const unsigned int NUM_FONT_WEIGHT_TYPE = sizeof( FONT_WEIGHT_TYPE_TO_INT ) / sizeof( int );
 
-// NORMAL, ROMAN   0
-// ITALIC        100
-// OBLIQUE       110
-const int FONT_SLANT_TYPE_TO_INT[] = { 0, 100, 110 };
+// NONE             -1 --> DEFAULT_FONT_SLANT (NORMAL) will be used.
+// NORMAL, ROMAN     0
+// ITALIC          100
+// OBLIQUE         110
+const int FONT_SLANT_TYPE_TO_INT[] = { -1, 0, 100, 110 };
 const unsigned int NUM_FONT_SLANT_TYPE = sizeof( FONT_SLANT_TYPE_TO_INT ) / sizeof( int );
 
 } // namespace
@@ -158,11 +161,11 @@ FontClient::Plugin::FontIdCacheItem::FontIdCacheItem( FontDescriptionId validate
 {
 }
 
-FontClient::Plugin::CacheItem::CacheItem( FT_Face ftFace,
-                                          const FontPath& path,
-                                          PointSize26Dot6 requestedPointSize,
-                                          FaceIndex face,
-                                          const FontMetrics& metrics )
+FontClient::Plugin::FontFaceCacheItem::FontFaceCacheItem( FT_Face ftFace,
+                                                          const FontPath& path,
+                                                          PointSize26Dot6 requestedPointSize,
+                                                          FaceIndex face,
+                                                          const FontMetrics& metrics )
 : mFreeTypeFace( ftFace ),
   mPath( path ),
   mRequestedPointSize( requestedPointSize ),
@@ -175,13 +178,13 @@ FontClient::Plugin::CacheItem::CacheItem( FT_Face ftFace,
 {
 }
 
-FontClient::Plugin::CacheItem::CacheItem( FT_Face ftFace,
-                                          const FontPath& path,
-                                          PointSize26Dot6 requestedPointSize,
-                                          FaceIndex face,
-                                          const FontMetrics& metrics,
-                                          float fixedWidth,
-                                          float fixedHeight )
+FontClient::Plugin::FontFaceCacheItem::FontFaceCacheItem( FT_Face ftFace,
+                                                          const FontPath& path,
+                                                          PointSize26Dot6 requestedPointSize,
+                                                          FaceIndex face,
+                                                          const FontMetrics& metrics,
+                                                          float fixedWidth,
+                                                          float fixedHeight )
 : mFreeTypeFace( ftFace ),
   mPath( path ),
   mRequestedPointSize( requestedPointSize ),
@@ -408,12 +411,11 @@ FontId FontClient::Plugin::FindFontForCharacter( const FontList& fontList,
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "FontClient::Plugin::FindFontForCharacter\n");
 
-  FontId fontId(0);
-  bool foundColor(false);
+  FontId fontId = 0u;
+  bool foundColor = false;
 
   // Traverse the list of fonts.
-  // Check for each default font if supports the character.
-
+  // Check for each font if supports the character.
   for( FontList::const_iterator it = fontList.begin(), endIt = fontList.end();
        it != endIt;
        ++it )
@@ -467,7 +469,7 @@ FontId FontClient::Plugin::FindFontForCharacter( const FontList& fontList,
         }
       }
 
-      // Keep going unless we prefer a different (color) font
+      // Keep going unless we prefer a different (color) font.
       if( !preferColor || foundColor )
       {
         FcPatternDestroy( match );
@@ -499,6 +501,7 @@ FontId FontClient::Plugin::FindDefaultFont( Character charcode,
     fontDescription.width = IntToWidthType( DEFAULT_FONT_WIDTH );
     fontDescription.weight = IntToWeightType( DEFAULT_FONT_WEIGHT );
     fontDescription.slant = IntToSlantType( DEFAULT_FONT_SLANT );
+
     SetFontList( fontDescription, mDefaultFonts );
   }
 
@@ -509,8 +512,8 @@ FontId FontClient::Plugin::FindDefaultFont( Character charcode,
   return fontId;
 }
 
-FontId FontClient::Plugin::FindFallbackFont( FontId preferredFont,
-                                             Character charcode,
+FontId FontClient::Plugin::FindFallbackFont( Character charcode,
+                                             const FontDescription& preferredFontDescription,
                                              PointSize26Dot6 requestedPointSize,
                                              bool preferColor )
 {
@@ -518,7 +521,12 @@ FontId FontClient::Plugin::FindFallbackFont( FontId preferredFont,
   FontId fontId = 0u;
 
   FontDescription fontDescription;
-  GetDescription( preferredFont, fontDescription );
+
+  // Fill the font description with the preferred font description and complete with the defaults.
+  fontDescription.family = preferredFontDescription.family.empty() ? DEFAULT_FONT_FAMILY_NAME : preferredFontDescription.family;
+  fontDescription.weight = ( ( FontWeight::NONE == preferredFontDescription.weight ) ? IntToWeightType( DEFAULT_FONT_WEIGHT ) : preferredFontDescription.weight );
+  fontDescription.width = ( ( FontWidth::NONE == preferredFontDescription.width ) ? IntToWidthType( DEFAULT_FONT_WIDTH ) : preferredFontDescription.width );
+  fontDescription.slant = ( ( FontSlant::NONE == preferredFontDescription.slant ) ? IntToSlantType( DEFAULT_FONT_SLANT ) : preferredFontDescription.slant );
 
   // Check first if the font's description has been queried before.
   FontList* fontList( NULL );
@@ -529,7 +537,7 @@ FontId FontClient::Plugin::FindFallbackFont( FontId preferredFont,
     SetFontList( fontDescription, *fontList );
 
     // Add the font-list to the cache.
-    mFallbackCache.push_back( FallbackCacheItem(fontDescription, fontList) );
+    mFallbackCache.push_back( FallbackCacheItem( fontDescription, fontList ) );
   }
 
   if( fontList )
@@ -683,7 +691,7 @@ void FontClient::Plugin::GetFontMetrics( FontId fontId,
   if( ( fontId > 0 ) &&
       ( fontId - 1u < mFontCache.size() ) )
   {
-    const CacheItem& font = mFontCache[fontId-1];
+    const FontFaceCacheItem& font = mFontCache[fontId-1];
 
     metrics = font.mMetrics;
 
@@ -754,7 +762,7 @@ bool FontClient::Plugin::GetBitmapMetrics( GlyphInfo* array,
     if( fontId > 0 &&
         fontId-1 < mFontCache.size() )
     {
-      const CacheItem& font = mFontCache[fontId-1];
+      const FontFaceCacheItem& font = mFontCache[fontId-1];
 
       FT_Face ftFace = font.mFreeTypeFace;
 
@@ -842,7 +850,7 @@ bool FontClient::Plugin::GetVectorMetrics( GlyphInfo* array,
     if( fontId > 0 &&
         fontId-1 < mFontCache.size() )
     {
-      CacheItem& font = mFontCache[fontId-1];
+      FontFaceCacheItem& font = mFontCache[fontId-1];
 
       if( ! font.mVectorFontId )
       {
@@ -942,7 +950,7 @@ void FontClient::Plugin::CreateVectorBlob( FontId fontId, GlyphIndex glyphIndex,
   if( fontId > 0 &&
       fontId-1 < mFontCache.size() )
   {
-    CacheItem& font = mFontCache[fontId-1];
+    FontFaceCacheItem& font = mFontCache[fontId-1];
 
     if( ! font.mVectorFontId )
     {
@@ -1056,6 +1064,7 @@ bool FontClient::Plugin::MatchFontDescriptionToPattern( FcPattern* pattern, Dali
     fontDescription.width = IntToWidthType( width );
     fontDescription.weight = IntToWeightType( weight );
     fontDescription.slant = IntToSlantType( slant );
+
     // destroyed the matched pattern
     FcPatternDestroy( match );
     ret = true;
@@ -1073,9 +1082,30 @@ FcPattern* FontClient::Plugin::CreateFontFamilyPattern( const FontDescription& f
   // add a property to the pattern for the font family
   FcPatternAddString( fontFamilyPattern, FC_FAMILY, reinterpret_cast<const FcChar8*>( fontDescription.family.c_str() ) );
 
-  FcPatternAddInteger( fontFamilyPattern, FC_WIDTH, FONT_WIDTH_TYPE_TO_INT[fontDescription.width] );
-  FcPatternAddInteger( fontFamilyPattern, FC_WEIGHT, FONT_WEIGHT_TYPE_TO_INT[fontDescription.weight] );
-  FcPatternAddInteger( fontFamilyPattern, FC_SLANT, FONT_SLANT_TYPE_TO_INT[fontDescription.slant] );
+  int width = FONT_WIDTH_TYPE_TO_INT[fontDescription.width];
+  if( width < 0 )
+  {
+    // Use default.
+    width = DEFAULT_FONT_WIDTH;
+  }
+
+  int weight = FONT_WEIGHT_TYPE_TO_INT[fontDescription.weight];
+  if( weight < 0 )
+  {
+    // Use default.
+    weight = DEFAULT_FONT_WEIGHT;
+  }
+
+  int slant = FONT_SLANT_TYPE_TO_INT[fontDescription.slant];
+  if( slant < 0 )
+  {
+    // Use default.
+    slant = DEFAULT_FONT_SLANT;
+  }
+
+  FcPatternAddInteger( fontFamilyPattern, FC_WIDTH, width );
+  FcPatternAddInteger( fontFamilyPattern, FC_WEIGHT, weight );
+  FcPatternAddInteger( fontFamilyPattern, FC_SLANT, slant );
 
   // Add a property of the pattern, to say we want to match TrueType fonts
   FcPatternAddString( fontFamilyPattern , FC_FONTFORMAT, reinterpret_cast<const FcChar8*>( FONT_FORMAT.c_str() ) );
@@ -1197,7 +1227,7 @@ FontId FontClient::Plugin::CreateFont( const FontPath& path,
                                  0.0f,
                                  0.0f );
 
-            mFontCache.push_back( CacheItem( ftFace, path, requestedPointSize, faceIndex, metrics, fixedWidth, fixedHeight ) );
+            mFontCache.push_back( FontFaceCacheItem( ftFace, path, requestedPointSize, faceIndex, metrics, fixedWidth, fixedHeight ) );
             id = mFontCache.size();
 
             if( cacheDescription )
@@ -1242,7 +1272,7 @@ FontId FontClient::Plugin::CreateFont( const FontPath& path,
                              static_cast< float >( ftFace->underline_position ) * FROM_266,
                              static_cast< float >( ftFace->underline_thickness ) * FROM_266 );
 
-        mFontCache.push_back( CacheItem( ftFace, path, requestedPointSize, faceIndex, metrics ) );
+        mFontCache.push_back( FontFaceCacheItem( ftFace, path, requestedPointSize, faceIndex, metrics ) );
         id = mFontCache.size();
 
         if( cacheDescription )
@@ -1311,12 +1341,12 @@ bool FontClient::Plugin::FindFont( const FontPath& path,
                                    FontId& fontId ) const
 {
   fontId = 0u;
-  for( std::vector<CacheItem>::const_iterator it = mFontCache.begin(),
+  for( std::vector<FontFaceCacheItem>::const_iterator it = mFontCache.begin(),
          endIt = mFontCache.end();
        it != endIt;
        ++it, ++fontId )
   {
-    const CacheItem& cacheItem = *it;
+    const FontFaceCacheItem& cacheItem = *it;
 
     if( cacheItem.mRequestedPointSize == requestedPointSize &&
         cacheItem.mFaceIndex == faceIndex &&
@@ -1524,9 +1554,9 @@ void FontClient::Plugin::CacheFontPath( FT_Face ftFace, FontId id, PointSize26Do
   FontDescription description;
   description.path = path;
   description.family = FontFamily( ftFace->family_name );
-  description.weight = FontWeight::NORMAL;
-  description.width = FontWidth::NORMAL;
-  description.slant = FontSlant::NORMAL;
+  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( ftFace->style_flags & FT_STYLE_FLAG_ITALIC )
index 4f191a6..aad7d54 100644 (file)
@@ -91,27 +91,27 @@ struct FontClient::Plugin
 
     FontDescriptionId validatedFontId;    ///< Index to the vector with font descriptions.
     PointSize26Dot6   requestedPointSize; ///< The font point size.
-    FontId            fontId;             ///< The font id.
+    FontId            fontId;             ///< The font identifier.
   };
 
   /**
    * @brief Caches the FreeType face and font metrics of the triplet 'path to the font file name, font point size and face index'.
    */
-  struct CacheItem
+  struct FontFaceCacheItem
   {
-    CacheItem( FT_Face ftFace,
-               const FontPath& path,
-               PointSize26Dot6 requestedPointSize,
-               FaceIndex face,
-               const FontMetrics& metrics );
-
-    CacheItem( FT_Face ftFace,
-               const FontPath& path,
-               PointSize26Dot6 requestedPointSize,
-               FaceIndex face,
-               const FontMetrics& metrics,
-               float fixedWidth,
-               float fixedHeight );
+    FontFaceCacheItem( FT_Face ftFace,
+                       const FontPath& path,
+                       PointSize26Dot6 requestedPointSize,
+                       FaceIndex face,
+                       const FontMetrics& metrics );
+
+    FontFaceCacheItem( FT_Face ftFace,
+                       const FontPath& path,
+                       PointSize26Dot6 requestedPointSize,
+                       FaceIndex face,
+                       const FontMetrics& metrics,
+                       float fixedWidth,
+                       float fixedHeight );
 
     FT_Face mFreeTypeFace;               ///< The FreeType face.
     FontPath mPath;                      ///< The path to the font file name.
@@ -161,7 +161,7 @@ struct FontClient::Plugin
   /**
    * @copydoc Dali::FontClient::SetDefaultFont()
    */
-  void SetDefaultFont( const FontDescription& fontDescription );
+  void SetDefaultFont( const FontDescription& preferredFontDescription );
 
   /**
    * @copydoc Dali::FontClient::GetDefaultPlatformFontDescription()
@@ -189,7 +189,14 @@ struct FontClient::Plugin
   PointSize26Dot6 GetPointSize( FontId id );
 
   /**
-   * @copydoc Dali::FontClient::FindFontForCharacter()
+   * @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] 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.
+   *
+   * @return A valid font identifier, or zero if no font is found.
    */
   FontId FindFontForCharacter( const FontList& fontList,
                                Character charcode,
@@ -199,12 +206,17 @@ struct FontClient::Plugin
   /**
    * @copydoc Dali::FontClient::FindDefaultFont()
    */
-  FontId FindDefaultFont( Character charcode, PointSize26Dot6 requestedPointSize, bool preferColor );
+  FontId FindDefaultFont( Character charcode,
+                          PointSize26Dot6 requestedPointSize,
+                          bool preferColor );
 
   /**
    * @copydoc Dali::FontClient::FindFallbackFont()
    */
-  FontId FindFallbackFont( FontId preferredFont, Character charcode, PointSize26Dot6 requestedPointSize, bool preferColor );
+  FontId FindFallbackFont( Character charcode,
+                           const FontDescription& preferredFontDescription,
+                           PointSize26Dot6 requestedPointSize,
+                           bool preferColor );
 
   /**
    * @see Dali::FontClient::GetFontId( const FontPath& path, PointSize26Dot6 requestedPointSize, FaceIndex faceIndex )
@@ -219,7 +231,9 @@ struct FontClient::Plugin
                     bool cacheDescription = true );
 
   /**
-   * @copydoc Dali::FontClient::GetFontId( const FontDescription& fontDescription, PointSize26Dot6 requestedPointSize, FaceIndex faceIndex )
+   * @see Dali::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.
    */
   FontId GetFontId( const FontDescription& fontDescription,
                     PointSize26Dot6 requestedPointSize,
@@ -351,7 +365,7 @@ private:
    * @param[in] faceIndex A face index.
    * @param[in] cacheDescription Whether to cache the font description.
    *
-   * @return The font id.
+   * @return The font identifier.
    */
   FontId CreateFont( const FontPath& path,
                      PointSize26Dot6 requestedPointSize,
@@ -368,12 +382,12 @@ private:
 
   /**
    * @brief Finds in the cache if there is a triplet with the path to the font file name, the font point size and the face index.
-   * If there is one , if writes the font id in the param @p fontId.
+   * If there is one , if writes the font identifier in the param @p fontId.
    *
    * @param[in] path Path to the font file name.
    * @param[in] requestedPointSize The font point size.
    * @param[in] faceIndex The face index.
-   * @param[out] fontId The font id.
+   * @param[out] fontId The font identifier.
    *
    * @return @e true if there triplet is found.
    */
@@ -401,12 +415,12 @@ private:
                              FontList*& fontList );
 
   /**
-   * @brief Finds in the cache a pair 'validated font id and font point size'.
-   * If there is one it writes the font id in the param @p fontId.
+   * @brief Finds in the cache a pair 'validated font identifier and font point size'.
+   * If there is one it writes the font identifier in the param @p fontId.
    *
    * @param[in] validatedFontId Index to the vector with font descriptions.
    * @param[in] requestedPointSize The font point size.
-   * @param[out] fontId The font id.
+   * @param[out] fontId The font identifier.
    *
    * @return @e true if the pair is found.
    */
@@ -462,10 +476,10 @@ private:
 
   std::vector<FallbackCacheItem> mFallbackCache; ///< Cached fallback font lists.
 
-  std::vector<CacheItem>                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<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.
-  std::vector<FontIdCacheItem>          mFontIdCache;          ///< Caches font ids for the pairs of font point size and the index to the vector with font descriptions of the validated fonts.
+  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.