Markup procesor - Font. 00/53800/12
authorVictor Cebollada <v.cebollada@samsung.com>
Wed, 25 Nov 2015 15:17:13 +0000 (15:17 +0000)
committerVictor Cebollada <v.cebollada@samsung.com>
Fri, 8 Jan 2016 16:08:41 +0000 (16:08 +0000)
Signed-off-by: Victor Cebollada <v.cebollada@samsung.com>
Change-Id: Icd3e97862b96f2631a17595136359a08fdfd2371

30 files changed:
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-MultiLanguage.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp
dali-toolkit/internal/controls/text-controls/text-field-impl.cpp
dali-toolkit/internal/controls/text-controls/text-font-style.cpp [deleted file]
dali-toolkit/internal/controls/text-controls/text-label-impl.cpp
dali-toolkit/internal/file.list
dali-toolkit/internal/text/font-description-run.h [new file with mode: 0644]
dali-toolkit/internal/text/font-run.h
dali-toolkit/internal/text/input-style.h
dali-toolkit/internal/text/logical-model-impl.cpp
dali-toolkit/internal/text/logical-model-impl.h
dali-toolkit/internal/text/markup-processor-font.cpp [new file with mode: 0644]
dali-toolkit/internal/text/markup-processor-font.h [new file with mode: 0644]
dali-toolkit/internal/text/markup-processor-helper-functions.cpp
dali-toolkit/internal/text/markup-processor-helper-functions.h
dali-toolkit/internal/text/markup-processor.cpp
dali-toolkit/internal/text/markup-processor.h
dali-toolkit/internal/text/multi-language-support-impl.cpp
dali-toolkit/internal/text/multi-language-support-impl.h
dali-toolkit/internal/text/multi-language-support.cpp
dali-toolkit/internal/text/multi-language-support.h
dali-toolkit/internal/text/text-controller-impl.cpp
dali-toolkit/internal/text/text-controller-impl.h
dali-toolkit/internal/text/text-controller.cpp
dali-toolkit/internal/text/text-controller.h
dali-toolkit/internal/text/text-font-style.cpp [new file with mode: 0644]
dali-toolkit/internal/text/text-font-style.h [moved from dali-toolkit/internal/controls/text-controls/text-font-style.h with 79% similarity]
dali-toolkit/public-api/controls/text-controls/text-field.h
docs/content/shared-javascript-and-cpp-documentation/markup-style.md
docs/content/shared-javascript-and-cpp-documentation/text-field.md

index 8ad3b15..11a2af7 100644 (file)
@@ -33,7 +33,11 @@ using namespace Text;
 // Tests the following functions with different scripts.
 // Constructor, destructor and MultilanguageSupport::Get()
 // void MultilanguageSupport::SetScripts( const Vector<Character>& text, const Vector<LineBreakInfo>& lineBreakInfo, Vector<ScriptRun>& scripts );
 // Tests the following functions with different scripts.
 // Constructor, destructor and MultilanguageSupport::Get()
 // void MultilanguageSupport::SetScripts( const Vector<Character>& text, const Vector<LineBreakInfo>& lineBreakInfo, Vector<ScriptRun>& scripts );
-// void MultilanguageSupport::ValidateFonts( const Vector<Character>& text, const Vector<ScriptRun>& scripts, Vector<FontRun>& fonts );
+// void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
+//                                           const Vector<ScriptRun>& scripts,
+//                                           const Vector<FontDescriptionRun>& fontDescriptions,
+//                                           FontId defaultFontId,
+//                                           Vector<FontRun>& fonts );
 
 //////////////////////////////////////////////////////////
 
 
 //////////////////////////////////////////////////////////
 
@@ -127,12 +131,17 @@ bool ValidateFontTest( const ValidateFontsData& data )
   multilanguageSupport.SetScripts( utf32,
                                    scripts );
 
   multilanguageSupport.SetScripts( utf32,
                                    scripts );
 
+  // To be completed ...
+  Vector<FontDescriptionRun> fontDescriptions;
+  FontId defaultFontId = 0u;
   Vector<FontRun> fonts;
   Vector<FontRun> fonts;
+
   // 3) Validate the fonts
   multilanguageSupport.ValidateFonts( utf32,
                                       scripts,
   // 3) Validate the fonts
   multilanguageSupport.ValidateFonts( utf32,
                                       scripts,
+                                      fontDescriptions,
+                                      defaultFontId,
                                       fonts );
                                       fonts );
-
   return true;
 }
 
   return true;
 }
 
index 9fe5e53..31e5126 100644 (file)
@@ -76,6 +76,9 @@ const char* const PROPERTY_NAME_DECORATION_BOUNDING_BOX              = "decorati
 const char* const PROPERTY_NAME_INPUT_METHOD_SETTINGS                = "inputMethodSettings";
 const char* const PROPERTY_NAME_INPUT_COLOR                          = "inputColor";
 const char* const PROPERTY_NAME_ENABLE_MARKUP                        = "enableMarkup";
 const char* const PROPERTY_NAME_INPUT_METHOD_SETTINGS                = "inputMethodSettings";
 const char* const PROPERTY_NAME_INPUT_COLOR                          = "inputColor";
 const char* const PROPERTY_NAME_ENABLE_MARKUP                        = "enableMarkup";
+const char* const PROPERTY_NAME_INPUT_FONT_FAMILY                    = "inputFontFamily";
+const char* const PROPERTY_NAME_INPUT_FONT_STYLE                     = "inputFontStyle";
+const char* const PROPERTY_NAME_INPUT_POINT_SIZE                     = "inputPointSize";
 
 const int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::Text::DEFAULT_RENDERING_BACKEND;
 
 
 const int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::Text::DEFAULT_RENDERING_BACKEND;
 
@@ -266,6 +269,9 @@ int UtcDaliTextFieldGetPropertyP(void)
   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_INPUT_METHOD_SETTINGS ) == TextField::Property::INPUT_METHOD_SETTINGS );
   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_INPUT_COLOR ) == TextField::Property::INPUT_COLOR );
   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_ENABLE_MARKUP ) == TextField::Property::ENABLE_MARKUP );
   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_INPUT_METHOD_SETTINGS ) == TextField::Property::INPUT_METHOD_SETTINGS );
   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_INPUT_COLOR ) == TextField::Property::INPUT_COLOR );
   DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_ENABLE_MARKUP ) == TextField::Property::ENABLE_MARKUP );
+  DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_INPUT_FONT_FAMILY ) == TextField::Property::INPUT_FONT_FAMILY );
+  DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_INPUT_FONT_STYLE ) == TextField::Property::INPUT_FONT_STYLE );
+  DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_INPUT_POINT_SIZE ) == TextField::Property::INPUT_POINT_SIZE );
   END_TEST;
 }
 
   END_TEST;
 }
 
@@ -393,7 +399,7 @@ int UtcDaliTextFieldSetPropertyP(void)
   field.SetProperty( TextField::Property::DECORATION_BOUNDING_BOX, Rect<int>( 0, 0, 1, 1 ) );
   DALI_TEST_EQUALS( field.GetProperty<Rect <int > >( TextField::Property::DECORATION_BOUNDING_BOX ), Rect<int>( 0, 0, 1, 1 ), TEST_LOCATION );
 
   field.SetProperty( TextField::Property::DECORATION_BOUNDING_BOX, Rect<int>( 0, 0, 1, 1 ) );
   DALI_TEST_EQUALS( field.GetProperty<Rect <int > >( TextField::Property::DECORATION_BOUNDING_BOX ), Rect<int>( 0, 0, 1, 1 ), TEST_LOCATION );
 
-  // Input color
+  // Check input color property.
   field.SetProperty( TextField::Property::INPUT_COLOR, Color::YELLOW );
   DALI_TEST_EQUALS( field.GetProperty<Vector4>( TextField::Property::INPUT_COLOR ), Color::YELLOW, TEST_LOCATION );
 
   field.SetProperty( TextField::Property::INPUT_COLOR, Color::YELLOW );
   DALI_TEST_EQUALS( field.GetProperty<Vector4>( TextField::Property::INPUT_COLOR ), Color::YELLOW, TEST_LOCATION );
 
@@ -402,6 +408,14 @@ int UtcDaliTextFieldSetPropertyP(void)
   field.SetProperty( TextField::Property::ENABLE_MARKUP, true );
   DALI_TEST_CHECK( field.GetProperty<bool>( TextField::Property::ENABLE_MARKUP ) );
 
   field.SetProperty( TextField::Property::ENABLE_MARKUP, true );
   DALI_TEST_CHECK( field.GetProperty<bool>( TextField::Property::ENABLE_MARKUP ) );
 
+  // Check input font properties.
+  field.SetProperty( TextField::Property::INPUT_FONT_FAMILY, "Setting input font family" );
+  DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::INPUT_FONT_FAMILY ), "Setting input font family", TEST_LOCATION );
+  field.SetProperty( TextField::Property::INPUT_FONT_STYLE, "Setting input font style" );
+  DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::INPUT_FONT_STYLE ), "Setting input font style", TEST_LOCATION );
+  field.SetProperty( TextField::Property::INPUT_POINT_SIZE, 12.f );
+  DALI_TEST_EQUALS( field.GetProperty<float>( TextField::Property::INPUT_POINT_SIZE ), 12.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+
   END_TEST;
 }
 
   END_TEST;
 }
 
index 8b7ea1d..a0417df 100644 (file)
@@ -30,8 +30,8 @@
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/text/rendering-backend.h>
 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/text/rendering-backend.h>
 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
-#include <dali-toolkit/internal/controls/text-controls/text-font-style.h>
 #include <dali-toolkit/internal/text/rendering/text-backend.h>
 #include <dali-toolkit/internal/text/rendering/text-backend.h>
+#include <dali-toolkit/internal/text/text-font-style.h>
 #include <dali-toolkit/internal/text/text-view.h>
 #include <dali-toolkit/internal/styling/style-manager-impl.h>
 
 #include <dali-toolkit/internal/text/text-view.h>
 #include <dali-toolkit/internal/styling/style-manager-impl.h>
 
@@ -120,6 +120,9 @@ DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "decorationBoundingBox",
 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputMethodSettings",                  MAP,       INPUT_METHOD_SETTINGS                )
 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputColor",                           VECTOR4,   INPUT_COLOR                          )
 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "enableMarkup",                         BOOLEAN,   ENABLE_MARKUP                        )
 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputMethodSettings",                  MAP,       INPUT_METHOD_SETTINGS                )
 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputColor",                           VECTOR4,   INPUT_COLOR                          )
 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "enableMarkup",                         BOOLEAN,   ENABLE_MARKUP                        )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputFontFamily",                      STRING,    INPUT_FONT_FAMILY                    )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputFontStyle",                       STRING,    INPUT_FONT_STYLE                     )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputPointSize",                       FLOAT,     INPUT_POINT_SIZE                     )
 
 DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "textChanged",        SIGNAL_TEXT_CHANGED )
 DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "maxLengthReached",   SIGNAL_MAX_LENGTH_REACHED )
 
 DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "textChanged",        SIGNAL_TEXT_CHANGED )
 DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "maxLengthReached",   SIGNAL_MAX_LENGTH_REACHED )
@@ -214,7 +217,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       }
       case Toolkit::TextField::Property::FONT_STYLE:
       {
       }
       case Toolkit::TextField::Property::FONT_STYLE:
       {
-        SetFontStyleProperty( impl.mController, value );
+        SetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT );
         break;
       }
       case Toolkit::TextField::Property::POINT_SIZE:
         break;
       }
       case Toolkit::TextField::Property::POINT_SIZE:
@@ -578,6 +581,31 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
         }
         break;
       }
         }
         break;
       }
+      case Toolkit::TextField::Property::INPUT_FONT_FAMILY:
+      {
+        if( impl.mController )
+        {
+          const std::string fontFamily = value.Get< std::string >();
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p INPUT_FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str() );
+          impl.mController->SetInputFontFamily( fontFamily );
+        }
+        break;
+      }
+      case Toolkit::TextField::Property::INPUT_FONT_STYLE:
+      {
+        SetFontStyleProperty( impl.mController, value, Text::FontStyle::INPUT );
+        break;
+      }
+      case Toolkit::TextField::Property::INPUT_POINT_SIZE:
+      {
+        if( impl.mController )
+        {
+          const float pointSize = value.Get< float >();
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p INPUT_POINT_SIZE %f\n", impl.mController.Get(), pointSize );
+          impl.mController->SetInputFontPointSize( pointSize );
+        }
+        break;
+      }
     } // switch
   } // textfield
 }
     } // switch
   } // textfield
 }
@@ -640,7 +668,7 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
       }
       case Toolkit::TextField::Property::FONT_STYLE:
       {
       }
       case Toolkit::TextField::Property::FONT_STYLE:
       {
-        GetFontStyleProperty( impl.mController, value );
+        GetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT );
         break;
       }
       case Toolkit::TextField::Property::POINT_SIZE:
         break;
       }
       case Toolkit::TextField::Property::POINT_SIZE:
@@ -708,14 +736,6 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
         }
         break;
       }
         }
         break;
       }
-      case Toolkit::TextField::Property::INPUT_COLOR:
-      {
-        if( impl.mController )
-        {
-          value = impl.mController->GetInputColor();
-        }
-        break;
-      }
       case Toolkit::TextField::Property::SHADOW_OFFSET:
       {
         if ( impl.mController )
       case Toolkit::TextField::Property::SHADOW_OFFSET:
       {
         if ( impl.mController )
@@ -869,6 +889,14 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
       {
         break;
       }
       {
         break;
       }
+      case Toolkit::TextField::Property::INPUT_COLOR:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->GetInputColor();
+        }
+        break;
+      }
       case Toolkit::TextField::Property::ENABLE_MARKUP:
       {
         if( impl.mController )
       case Toolkit::TextField::Property::ENABLE_MARKUP:
       {
         if( impl.mController )
@@ -877,6 +905,27 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
         }
         break;
       }
         }
         break;
       }
+      case Toolkit::TextField::Property::INPUT_FONT_FAMILY:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->GetInputFontFamily();
+        }
+        break;
+      }
+      case Toolkit::TextField::Property::INPUT_FONT_STYLE:
+      {
+        GetFontStyleProperty( impl.mController, value, Text::FontStyle::INPUT );
+        break;
+      }
+      case Toolkit::TextField::Property::INPUT_POINT_SIZE:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->GetInputFontPointSize();
+        }
+        break;
+      }
     } //switch
   }
 
     } //switch
   }
 
diff --git a/dali-toolkit/internal/controls/text-controls/text-font-style.cpp b/dali-toolkit/internal/controls/text-controls/text-font-style.cpp
deleted file mode 100644 (file)
index 2c29f68..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// FILE HEADER
-#include <dali-toolkit/internal/controls/text-controls/text-font-style.h>
-
-// INTERNAL INCLUDES
-#include <dali-toolkit/devel-api/builder/json-parser.h>
-#include <dali-toolkit/devel-api/builder/tree-node.h>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Text
-{
-
-namespace
-{
-const std::string STYLE_KEY( "style" );
-const std::string WIDTH_KEY( "width" );
-const std::string WEIGHT_KEY( "weight" );
-const std::string SLANT_KEY( "slant" );
-const std::string EMPTY_STRING( "" );
-
-} // namespace
-
-/**
- * @brief Creates a map with pairs 'key,value' with the font's style parameters.
- *
- * @param[in] node Data structure with the font's style parameters.
- * @param[out] map A map with the font's style parameters.
- *
- */
-void CreateFontStyleMap( const TreeNode* const node, Property::Map& map )
-{
-  switch( node->GetType() )
-  {
-    case TreeNode::IS_NULL:
-    case TreeNode::OBJECT:
-    case TreeNode::ARRAY: // FALL THROUGH
-    {
-      break;
-    }
-    case TreeNode::STRING:
-    {
-      map.Insert( node->GetName(), Property::Value( node->GetString() ) );
-      break;
-    }
-    case TreeNode::INTEGER:
-    case TreeNode::FLOAT:
-    case TreeNode::BOOLEAN: // FALL THROUGH
-    {
-      break;
-    }
-  }
-
-  for( TreeNode::ConstIterator it = node->CBegin(), endIt = node->CEnd(); it != endIt; ++it )
-  {
-    const TreeNode::KeyNodePair& pair = *it;
-    CreateFontStyleMap( &pair.second, map );
-  }
-}
-
-/**
- * @brief Parses the font's style string.
- *
- * @param[in] style The font's style string.
- * @param[out] map A map with the font's style parameters.
- *
- */
-void ParseFontStyleString( const std::string& style, Property::Map& map )
-{
-  Toolkit::JsonParser parser = Toolkit::JsonParser::New();
-
-  if( parser.Parse( style ) )
-  {
-    const TreeNode* const node = parser.GetRoot();
-
-    CreateFontStyleMap( node, map );
-  }
-}
-
-void SetFontStyleProperty( ControllerPtr controller, const Property::Value& value )
-{
-  if( controller )
-  {
-    const std::string style = value.Get< std::string >();
-
-    // Stores the string to be recovered by the GetFontStyleProperty() function.
-    controller->SetDefaultFontStyle( style );
-
-    // Parses and applies the style.
-    Property::Map map;
-    ParseFontStyleString( style, map );
-
-    if( !map.Empty() )
-    {
-      /// Width key
-      Property::Value* widthValue = map.Find( WIDTH_KEY );
-
-      if( widthValue )
-      {
-        const std::string widthStr = widthValue->Get<std::string>();
-
-        FontWidth width = TextAbstraction::FontWidth::NORMAL;
-        if( Scripting::GetEnumeration< FontWidth >( widthStr.c_str(),
-                                                    FONT_WIDTH_STRING_TABLE,
-                                                    FONT_WIDTH_STRING_TABLE_COUNT,
-                                                    width ) )
-        {
-          if( controller->GetDefaultFontWidth() != width )
-          {
-            controller->SetDefaultFontWidth( width );
-          }
-        }
-      }
-      else
-      {
-        controller->SetDefaultFontWidth( TextAbstraction::FontWidth::NORMAL );
-      }
-
-      /// Weight key
-      Property::Value* weightValue = map.Find( WEIGHT_KEY );
-
-      if( weightValue )
-      {
-        const std::string weightStr = weightValue->Get<std::string>();
-
-        FontWeight weight = TextAbstraction::FontWeight::NORMAL;
-        if( Scripting::GetEnumeration< FontWeight >( weightStr.c_str(),
-                                                     FONT_WEIGHT_STRING_TABLE,
-                                                     FONT_WEIGHT_STRING_TABLE_COUNT,
-                                                     weight ) )
-        {
-          if( controller->GetDefaultFontWeight() != weight )
-          {
-            controller->SetDefaultFontWeight( weight );
-          }
-        }
-      }
-      else
-      {
-        controller->SetDefaultFontWeight( TextAbstraction::FontWeight::NORMAL );
-      }
-
-      /// Slant key
-      Property::Value* slantValue = map.Find( SLANT_KEY );
-
-      if( slantValue )
-      {
-        const std::string slantStr = slantValue->Get<std::string>();
-
-        FontSlant slant = TextAbstraction::FontSlant::NORMAL;
-        if( Scripting::GetEnumeration< FontSlant >( slantStr.c_str(),
-                                                    FONT_SLANT_STRING_TABLE,
-                                                    FONT_SLANT_STRING_TABLE_COUNT,
-                                                    slant ) )
-        {
-          if( controller->GetDefaultFontSlant() != slant )
-          {
-            controller->SetDefaultFontSlant( slant );
-          }
-        }
-      }
-      else
-      {
-        controller->SetDefaultFontSlant( TextAbstraction::FontSlant::NORMAL );
-      }
-    }
-  }
-}
-
-void GetFontStyleProperty( ControllerPtr controller, Property::Value& value )
-{
-  if( controller )
-  {
-    value = controller->GetDefaultFontStyle();
-  }
-}
-
-} // namespace Text
-
-} // namespace Toolkit
-
-} // namespace Dali
index 0094c9b..f717bbf 100644 (file)
@@ -25,8 +25,8 @@
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/text/rendering-backend.h>
 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/text/rendering-backend.h>
 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
-#include <dali-toolkit/internal/controls/text-controls/text-font-style.h>
 #include <dali-toolkit/internal/text/rendering/text-backend.h>
 #include <dali-toolkit/internal/text/rendering/text-backend.h>
+#include <dali-toolkit/internal/text/text-font-style.h>
 #include <dali-toolkit/internal/text/text-view.h>
 #include <dali-toolkit/internal/styling/style-manager-impl.h>
 
 #include <dali-toolkit/internal/text/text-view.h>
 #include <dali-toolkit/internal/styling/style-manager-impl.h>
 
@@ -156,7 +156,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
       }
       case Toolkit::TextLabel::Property::FONT_STYLE:
       {
       }
       case Toolkit::TextLabel::Property::FONT_STYLE:
       {
-        SetFontStyleProperty( impl.mController, value );
+        SetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT );
         break;
       }
       case Toolkit::TextLabel::Property::POINT_SIZE:
         break;
       }
       case Toolkit::TextLabel::Property::POINT_SIZE:
@@ -340,7 +340,7 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde
       }
       case Toolkit::TextLabel::Property::FONT_STYLE:
       {
       }
       case Toolkit::TextLabel::Property::FONT_STYLE:
       {
-        GetFontStyleProperty( impl.mController, value );
+        GetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT );
         break;
       }
       case Toolkit::TextLabel::Property::POINT_SIZE:
         break;
       }
       case Toolkit::TextLabel::Property::POINT_SIZE:
index 6a8f4dc..345c107 100644 (file)
@@ -61,7 +61,6 @@ toolkit_src_files = \
    $(toolkit_src_dir)/controls/super-blur-view/super-blur-view-impl.cpp \
    $(toolkit_src_dir)/controls/table-view/table-view-impl.cpp \
    $(toolkit_src_dir)/controls/text-controls/text-field-impl.cpp \
    $(toolkit_src_dir)/controls/super-blur-view/super-blur-view-impl.cpp \
    $(toolkit_src_dir)/controls/table-view/table-view-impl.cpp \
    $(toolkit_src_dir)/controls/text-controls/text-field-impl.cpp \
-   $(toolkit_src_dir)/controls/text-controls/text-font-style.cpp \
    $(toolkit_src_dir)/controls/text-controls/text-label-impl.cpp \
    $(toolkit_src_dir)/controls/text-controls/text-selection-popup-impl.cpp \
    $(toolkit_src_dir)/controls/text-controls/text-selection-toolbar-impl.cpp \
    $(toolkit_src_dir)/controls/text-controls/text-label-impl.cpp \
    $(toolkit_src_dir)/controls/text-controls/text-selection-popup-impl.cpp \
    $(toolkit_src_dir)/controls/text-controls/text-selection-toolbar-impl.cpp \
@@ -87,6 +86,7 @@ toolkit_src_files = \
    $(toolkit_src_dir)/text/logical-model-impl.cpp \
    $(toolkit_src_dir)/text/markup-processor.cpp \
    $(toolkit_src_dir)/text/markup-processor-color.cpp \
    $(toolkit_src_dir)/text/logical-model-impl.cpp \
    $(toolkit_src_dir)/text/markup-processor.cpp \
    $(toolkit_src_dir)/text/markup-processor-color.cpp \
+   $(toolkit_src_dir)/text/markup-processor-font.cpp \
    $(toolkit_src_dir)/text/markup-processor-helper-functions.cpp \
    $(toolkit_src_dir)/text/multi-language-support.cpp \
    $(toolkit_src_dir)/text/segmentation.cpp \
    $(toolkit_src_dir)/text/markup-processor-helper-functions.cpp \
    $(toolkit_src_dir)/text/multi-language-support.cpp \
    $(toolkit_src_dir)/text/segmentation.cpp \
@@ -94,6 +94,7 @@ toolkit_src_files = \
    $(toolkit_src_dir)/text/text-control-interface.cpp \
    $(toolkit_src_dir)/text/text-controller.cpp \
    $(toolkit_src_dir)/text/text-controller-impl.cpp \
    $(toolkit_src_dir)/text/text-control-interface.cpp \
    $(toolkit_src_dir)/text/text-controller.cpp \
    $(toolkit_src_dir)/text/text-controller-impl.cpp \
+   $(toolkit_src_dir)/text/text-font-style.cpp \
    $(toolkit_src_dir)/text/text-io.cpp \
    $(toolkit_src_dir)/text/text-view.cpp \
    $(toolkit_src_dir)/text/text-view-interface.cpp \
    $(toolkit_src_dir)/text/text-io.cpp \
    $(toolkit_src_dir)/text/text-view.cpp \
    $(toolkit_src_dir)/text/text-view-interface.cpp \
diff --git a/dali-toolkit/internal/text/font-description-run.h b/dali-toolkit/internal/text/font-description-run.h
new file mode 100644 (file)
index 0000000..ada640c
--- /dev/null
@@ -0,0 +1,63 @@
+#ifndef __DALI_TOOLKIT_TEXT_FONT_DESCRIPTION_RUN_H__
+#define __DALI_TOOLKIT_TEXT_FONT_DESCRIPTION_RUN_H__
+
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/text-abstraction/font-list.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/character-run.h>
+#include <dali-toolkit/internal/text/text-definitions.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+/**
+ * @brief Run of characters with the same font.
+ */
+struct FontDescriptionRun
+{
+  CharacterRun    characterRun; ///< The initial character index and the number of characters of the run.
+  char*           familyName;   ///< The font's family name.
+  Length          familyLength; ///< The length of the font's family name.
+  FontWeight      weight;       ///< The font's weight.
+  FontWidth       width;        ///< The font's width.
+  FontSlant       slant;        ///< The font's slant.
+  PointSize26Dot6 size;         ///< The font's size.
+
+  bool familyDefined : 1; ///< Whether the font's family is defined.
+  bool weightDefined : 1; ///< Whether the font's weight is defined.
+  bool widthDefined  : 1; ///< Whether the font's width is defined.
+  bool slantDefined  : 1; ///< Whether the font's slant is defined.
+  bool sizeDefined   : 1; ///< Whether the font's size is defined.
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_FONT_DESCRIPTION_RUN_H__
index 2a9680a..6027ef7 100644 (file)
@@ -37,7 +37,6 @@ struct FontRun
 {
   CharacterRun characterRun; ///< The initial character index and the number of characters of the run.
   FontId       fontId;       ///< Font id of the run.
 {
   CharacterRun characterRun; ///< The initial character index and the number of characters of the run.
   FontId       fontId;       ///< Font id of the run.
-  bool         isDefault;    ///< Whether the font is a default font not defined by the user.
 };
 
 } // namespace Text
 };
 
 } // namespace Text
index cd562ec..a9e6eab 100644 (file)
@@ -21,6 +21,9 @@
 // EXTERNAL INCLUDES
 #include <dali/public-api/math/vector4.h>
 
 // EXTERNAL INCLUDES
 #include <dali/public-api/math/vector4.h>
 
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/text-definitions.h>
+
 namespace Dali
 {
 
 namespace Dali
 {
 
@@ -35,7 +38,37 @@ namespace Text
  */
 struct InputStyle
 {
  */
 struct InputStyle
 {
-Vector4 textColor;
+  InputStyle()
+  : textColor( Color::BLACK ),
+    fontStyle(),
+    familyName(),
+    weight( TextAbstraction::FontWeight::NORMAL ),
+    width( TextAbstraction::FontWidth::NORMAL ),
+    slant( TextAbstraction::FontSlant::NORMAL ),
+    size( 0.f ),
+    familyDefined( false ),
+    weightDefined( false ),
+    widthDefined( false ),
+    slantDefined( false ),
+    sizeDefined( false )
+  {}
+
+  ~InputStyle()
+  {};
+
+  Vector4     textColor;  ///< The text's color.
+  std::string fontStyle;  ///< The font's style string.
+  std::string familyName; ///< The font's family name.
+  FontWeight  weight;     ///< The font's weight.
+  FontWidth   width;      ///< The font's width.
+  FontSlant   slant;      ///< The font's slant.
+  float       size;       ///< The font's size.
+
+  bool        familyDefined : 1; ///< Whether the font's family is defined.
+  bool        weightDefined : 1; ///< Whether the font's weight is defined.
+  bool        widthDefined  : 1; ///< Whether the font's width is defined.
+  bool        slantDefined  : 1; ///< Whether the font's slant is defined.
+  bool        sizeDefined   : 1; ///< Whether the font's size is defined.
 };
 
 } // namespace Text
 };
 
 } // namespace Text
index bdbbbfe..d4a9d94 100644 (file)
@@ -31,6 +31,19 @@ namespace Toolkit
 namespace Text
 {
 
 namespace Text
 {
 
+void FreeFontFamilyNames( Vector<FontDescriptionRun>& fontDescriptionRuns )
+{
+  for( Vector<FontDescriptionRun>::Iterator it = fontDescriptionRuns.Begin(),
+         endIt = fontDescriptionRuns.End();
+       it != endIt;
+       ++it )
+  {
+    delete (*it).familyName;
+  }
+
+  fontDescriptionRuns.Clear();
+}
+
 LogicalModelPtr LogicalModel::New()
 {
   return LogicalModelPtr( new LogicalModel() );
 LogicalModelPtr LogicalModel::New()
 {
   return LogicalModelPtr( new LogicalModel() );
@@ -256,16 +269,28 @@ void LogicalModel::UpdateTextStyleRuns( CharacterIndex index, int numberOfCharac
                                  totalNumberOfCharacters,
                                  mColorRuns,
                                  removedColorRuns );
                                  totalNumberOfCharacters,
                                  mColorRuns,
                                  removedColorRuns );
+
+  // Process the font description runs.
+  Vector<FontDescriptionRun> removedFontDescriptionRuns;
+  UpdateCharacterRuns<FontDescriptionRun>( index,
+                                           numberOfCharacters,
+                                           totalNumberOfCharacters,
+                                           mFontDescriptionRuns,
+                                           removedFontDescriptionRuns );
+
+  // Free memory allocated for the font family name.
+  FreeFontFamilyNames( removedFontDescriptionRuns );
 }
 
 void LogicalModel::RetrieveStyle( CharacterIndex index, InputStyle& style )
 {
   unsigned int runIndex = 0u;
 }
 
 void LogicalModel::RetrieveStyle( CharacterIndex index, InputStyle& style )
 {
   unsigned int runIndex = 0u;
-  unsigned int lastRunIndex = 0u;
-  bool overriden = false;
 
   // Set the text color.
 
   // Set the text color.
-  for( Vector<ColorRun>::ConstIterator it = mColorRuns.Begin(),
+  bool colorOverriden = false;
+  unsigned int colorIndex = 0u;
+  const ColorRun* const colorRunsBuffer = mColorRuns.Begin();
+  for( Vector<ColorRun>::ConstIterator it = colorRunsBuffer,
          endIt = mColorRuns.End();
        it != endIt;
        ++it, ++runIndex )
          endIt = mColorRuns.End();
        it != endIt;
        ++it, ++runIndex )
@@ -275,20 +300,131 @@ void LogicalModel::RetrieveStyle( CharacterIndex index, InputStyle& style )
     if( ( colorRun.characterRun.characterIndex <= index ) &&
         ( index < colorRun.characterRun.characterIndex + colorRun.characterRun.numberOfCharacters ) )
     {
     if( ( colorRun.characterRun.characterIndex <= index ) &&
         ( index < colorRun.characterRun.characterIndex + colorRun.characterRun.numberOfCharacters ) )
     {
-      lastRunIndex = runIndex;
-      overriden = true;
+      colorIndex = runIndex;
+      colorOverriden = true;
     }
   }
 
   // Set the text's color if it's overriden.
     }
   }
 
   // Set the text's color if it's overriden.
-  if( overriden )
+  if( colorOverriden )
   {
   {
-    style.textColor = ( *( mColorRuns.Begin() + lastRunIndex ) ).color;
+    style.textColor = ( *( colorRunsBuffer + colorIndex ) ).color;
   }
   }
+
+  // Reset the run index.
+  runIndex = 0u;
+
+  // Set the font's parameters.
+  bool nameOverriden = false;
+  bool weightOverriden = false;
+  bool widthOverriden = false;
+  bool slantOverriden = false;
+  bool sizeOverriden = false;
+  unsigned int nameIndex = 0u;
+  unsigned int weightIndex = 0u;
+  unsigned int widthIndex = 0u;
+  unsigned int slantIndex = 0u;
+  unsigned int sizeIndex = 0u;
+  const FontDescriptionRun* const fontDescriptionRunsBuffer = mFontDescriptionRuns.Begin();
+  for( Vector<FontDescriptionRun>::ConstIterator it = fontDescriptionRunsBuffer,
+         endIt = mFontDescriptionRuns.End();
+       it != endIt;
+       ++it, ++runIndex )
+  {
+    const FontDescriptionRun& fontDescriptionRun = *it;
+
+    if( ( fontDescriptionRun.characterRun.characterIndex <= index ) &&
+        ( index < fontDescriptionRun.characterRun.characterIndex + fontDescriptionRun.characterRun.numberOfCharacters ) )
+    {
+      if( fontDescriptionRun.familyDefined )
+      {
+        nameIndex = runIndex;
+        nameOverriden = true;
+      }
+
+      if( fontDescriptionRun.weightDefined )
+      {
+        weightIndex = runIndex;
+        weightOverriden = true;
+      }
+
+      if( fontDescriptionRun.widthDefined )
+      {
+        widthIndex = runIndex;
+        widthOverriden = true;
+      }
+
+      if( fontDescriptionRun.slantDefined )
+      {
+        slantIndex = runIndex;
+        slantOverriden = true;
+      }
+
+      if( fontDescriptionRun.sizeDefined )
+      {
+        sizeIndex = runIndex;
+        sizeOverriden = true;
+      }
+    }
+  }
+
+  // Set the font's family name if it's overriden.
+  if( nameOverriden )
+  {
+    const FontDescriptionRun& fontDescriptionRun = *( fontDescriptionRunsBuffer + nameIndex );
+
+    style.familyName = std::string( fontDescriptionRun.familyName, fontDescriptionRun.familyLength );
+    style.familyDefined = true;
+  }
+
+  // Set the font's weight if it's overriden.
+  if( weightOverriden )
+  {
+    const FontDescriptionRun& fontDescriptionRun = *( fontDescriptionRunsBuffer + weightIndex );
+
+    style.weight = fontDescriptionRun.weight;
+    style.weightDefined = true;
+  }
+
+  // Set the font's width if it's overriden.
+  if( widthOverriden )
+  {
+    const FontDescriptionRun& fontDescriptionRun = *( fontDescriptionRunsBuffer + widthIndex );
+
+    style.width = fontDescriptionRun.width;
+    style.widthDefined = true;
+  }
+
+  // Set the font's slant if it's overriden.
+  if( slantOverriden )
+  {
+    const FontDescriptionRun& fontDescriptionRun = *( fontDescriptionRunsBuffer + slantIndex );
+
+    style.slant = fontDescriptionRun.slant;
+    style.slantDefined = true;
+  }
+
+  // Set the font's size if it's overriden.
+  if( sizeOverriden )
+  {
+    const FontDescriptionRun& fontDescriptionRun = *( fontDescriptionRunsBuffer + sizeIndex );
+
+    style.size = static_cast<float>( fontDescriptionRun.size ) / 64.f;
+    style.sizeDefined = true;
+  }
+
+  // Reset the run index.
+  runIndex = 0u;
+}
+
+void LogicalModel::ClearFontDescriptionRuns()
+{
+  FreeFontFamilyNames( mFontDescriptionRuns );
 }
 
 LogicalModel::~LogicalModel()
 {
 }
 
 LogicalModel::~LogicalModel()
 {
+  ClearFontDescriptionRuns();
 }
 
 LogicalModel::LogicalModel()
 }
 
 LogicalModel::LogicalModel()
index 6842cf6..7a28ba6 100644 (file)
@@ -28,6 +28,7 @@
 #include <dali-toolkit/internal/text/bidirectional-paragraph-info-run.h>
 #include <dali-toolkit/internal/text/color-run.h>
 #include <dali-toolkit/internal/text/font-run.h>
 #include <dali-toolkit/internal/text/bidirectional-paragraph-info-run.h>
 #include <dali-toolkit/internal/text/color-run.h>
 #include <dali-toolkit/internal/text/font-run.h>
+#include <dali-toolkit/internal/text/font-description-run.h>
 #include <dali-toolkit/internal/text/script-run.h>
 
 namespace Dali
 #include <dali-toolkit/internal/text/script-run.h>
 
 namespace Dali
@@ -124,6 +125,11 @@ public:
    */
   void RetrieveStyle( CharacterIndex index, InputStyle& style );
 
    */
   void RetrieveStyle( CharacterIndex index, InputStyle& style );
 
+  /**
+   * @brief Clears the font description runs.
+   */
+  void ClearFontDescriptionRuns();
+
 protected:
 
   /**
 protected:
 
   /**
@@ -150,6 +156,7 @@ public:
   Vector<ScriptRun>                     mScriptRuns;
   Vector<FontRun>                       mFontRuns;
   Vector<ColorRun>                      mColorRuns;
   Vector<ScriptRun>                     mScriptRuns;
   Vector<FontRun>                       mFontRuns;
   Vector<ColorRun>                      mColorRuns;
+  Vector<FontDescriptionRun>            mFontDescriptionRuns;
   Vector<LineBreakInfo>                 mLineBreakInfo;
   Vector<WordBreakInfo>                 mWordBreakInfo;
   Vector<BidirectionalParagraphInfoRun> mBidirectionalParagraphInfo;
   Vector<LineBreakInfo>                 mLineBreakInfo;
   Vector<WordBreakInfo>                 mWordBreakInfo;
   Vector<BidirectionalParagraphInfoRun> mBidirectionalParagraphInfo;
diff --git a/dali-toolkit/internal/text/markup-processor-font.cpp b/dali-toolkit/internal/text/markup-processor-font.cpp
new file mode 100644 (file)
index 0000000..b745317
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// FILE HEADER
+#include <dali-toolkit/internal/text/markup-processor-font.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/dali-vector.h>
+#include <memory.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/font-description-run.h>
+#include <dali-toolkit/internal/text/markup-processor-helper-functions.h>
+#include <dali-toolkit/internal/text/text-font-style.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+namespace
+{
+const std::string XHTML_FAMILY_ATTRIBUTE("family");
+const std::string XHTML_SIZE_ATTRIBUTE("size");
+const std::string XHTML_WEIGHT_ATTRIBUTE("weight");
+const std::string XHTML_WIDTH_ATTRIBUTE("width");
+const std::string XHTML_SLANT_ATTRIBUTE("slant");
+
+const unsigned int MAX_FONT_ATTRIBUTE_SIZE = 15u; ///< The maximum length of any of the possible 'weight', 'width' or 'slant' values.
+}
+
+void ProcessFontTag( const Tag& tag, FontDescriptionRun& fontRun )
+{
+  for( Vector<Attribute>::ConstIterator it = tag.attributes.Begin(),
+         endIt = tag.attributes.End();
+       it != endIt;
+       ++it )
+  {
+    const Attribute& attribute( *it );
+    if( TokenComparison( XHTML_FAMILY_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength ) )
+    {
+      fontRun.familyDefined = true;
+      fontRun.familyLength = attribute.valueLength;
+      fontRun.familyName = new char[fontRun.familyLength];
+      memcpy( fontRun.familyName, attribute.valueBuffer, fontRun.familyLength );
+      // The memory is freed when the font run is removed from the logical model.
+    }
+    else if( TokenComparison( XHTML_SIZE_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength ) )
+    {
+      // 64.f is used to convert from point size to 26.6 pixel format.
+      fontRun.size = static_cast<PointSize26Dot6>( StringToFloat( attribute.valueBuffer ) * 64.f );
+      fontRun.sizeDefined = true;
+    }
+    else if( TokenComparison( XHTML_WEIGHT_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength ) )
+    {
+      // The StringToWeight() uses the Scripting::GetEnumeration() function which requires the input string to end with a '\0' char.
+      char value[MAX_FONT_ATTRIBUTE_SIZE+1u];
+      const Length length = attribute.valueLength > MAX_FONT_ATTRIBUTE_SIZE ? MAX_FONT_ATTRIBUTE_SIZE : attribute.valueLength;
+      memcpy( value, attribute.valueBuffer, length );
+      value[length] = 0;
+
+      fontRun.weight = StringToWeight( value );
+      fontRun.weightDefined = true;
+    }
+    else if( TokenComparison( XHTML_WIDTH_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength ) )
+    {
+      // The StringToWidth() uses the Scripting::GetEnumeration() function which requires the input string to end with a '\0' char.
+      char value[MAX_FONT_ATTRIBUTE_SIZE+1u];
+      const Length length = attribute.valueLength > MAX_FONT_ATTRIBUTE_SIZE ? MAX_FONT_ATTRIBUTE_SIZE : attribute.valueLength;
+      memcpy( value, attribute.valueBuffer, length );
+      value[length] = 0;
+
+      fontRun.width = StringToWidth( value );
+      fontRun.widthDefined = true;
+    }
+    else if( TokenComparison( XHTML_SLANT_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength ) )
+    {
+      // The StringToSlant() uses the Scripting::GetEnumeration() function which requires the input string to end with a '\0' char.
+      char value[MAX_FONT_ATTRIBUTE_SIZE+1u];
+      const Length length = attribute.valueLength > MAX_FONT_ATTRIBUTE_SIZE ? MAX_FONT_ATTRIBUTE_SIZE : attribute.valueLength;
+      memcpy( value, attribute.valueBuffer, length );
+      value[length] = 0;
+
+      fontRun.slant = StringToSlant( value );
+      fontRun.slantDefined = true;
+    }
+  }
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/text/markup-processor-font.h b/dali-toolkit/internal/text/markup-processor-font.h
new file mode 100644 (file)
index 0000000..c804011
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef __DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_FONT_H__
+#define __DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_FONT_H__
+
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+struct Tag;
+struct FontDescriptionRun;
+
+/**
+ * @brief Retrieves the font attributes from the tag and sets it to the font run.
+ *
+ * @param[in] tag The font tag and its attributes.
+ * @param[in,out] fontRun The font description run.
+ */
+void ProcessFontTag( const Tag& tag, FontDescriptionRun& fontRun );
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_FONT_H__
index c460747..3c02c27 100644 (file)
@@ -86,6 +86,11 @@ unsigned int StringToHex( const char* const uintStr )
   return static_cast<unsigned int>( strtoul( uintStr, NULL, 16 ) );
 }
 
   return static_cast<unsigned int>( strtoul( uintStr, NULL, 16 ) );
 }
 
+float StringToFloat( const char* const floatStr )
+{
+  return static_cast<float>( strtod( floatStr, NULL ) );
+}
+
 void UintColorToVector4( unsigned int color, Vector4& retColor )
 {
   retColor.a = static_cast<float>( ( color & 0xFF000000 ) >> 24u ) / 255.f;
 void UintColorToVector4( unsigned int color, Vector4& retColor )
 {
   retColor.a = static_cast<float>( ( color & 0xFF000000 ) >> 24u ) / 255.f;
index 5934467..62be6c8 100644 (file)
@@ -94,6 +94,15 @@ void SkipWhiteSpace( const char*& markupStringBuffer,
 unsigned int StringToHex( const char* const uintStr );
 
 /**
 unsigned int StringToHex( const char* const uintStr );
 
 /**
+ * @brief Converts a string into a float value.
+ *
+ * @param[in] floatStr A float packed inside a string.
+ *
+ * @return The float value.
+ */
+float StringToFloat( const char* const floatStr );
+
+/**
  * @brief Converts an ARGB color packed in 4 byte unsigned int into a Vector4 color used in Dali.
  *
  * @param[in] color An ARGB color packed in an unsigned int.
  * @brief Converts an ARGB color packed in 4 byte unsigned int into a Vector4 color used in Dali.
  *
  * @param[in] color An ARGB color packed in an unsigned int.
index 51a1efb..53ccf0b 100644 (file)
@@ -21,6 +21,7 @@
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/character-set-conversion.h>
 #include <dali-toolkit/internal/text/markup-processor-color.h>
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/character-set-conversion.h>
 #include <dali-toolkit/internal/text/markup-processor-color.h>
+#include <dali-toolkit/internal/text/markup-processor-font.h>
 #include <dali-toolkit/internal/text/markup-processor-helper-functions.h>
 
 namespace Dali
 #include <dali-toolkit/internal/text/markup-processor-helper-functions.h>
 
 namespace Dali
@@ -58,7 +59,6 @@ const char BACK_SLASH        = '\\';
 const char WHITE_SPACE       = 0x20; // ASCII value of the white space.
 
 const unsigned int MAX_NUM_OF_ATTRIBUTES =  5u; ///< The font tag has the 'family', 'size' 'weight', 'width' and 'slant' attrubutes.
 const char WHITE_SPACE       = 0x20; // ASCII value of the white space.
 
 const unsigned int MAX_NUM_OF_ATTRIBUTES =  5u; ///< The font tag has the 'family', 'size' 'weight', 'width' and 'slant' attrubutes.
-
 const unsigned int DEFAULT_VECTOR_SIZE   = 16u; ///< Default size of run vectors.
 
 /**
 const unsigned int DEFAULT_VECTOR_SIZE   = 16u; ///< Default size of run vectors.
 
 /**
@@ -347,9 +347,11 @@ void ProcessMarkupString( const std::string& markupString, MarkupProcessData& ma
 
   // Points the next free position in the vector of runs.
   StyleStack::RunIndex colorRunIndex = 0u;
 
   // Points the next free position in the vector of runs.
   StyleStack::RunIndex colorRunIndex = 0u;
+  StyleStack::RunIndex fontRunIndex = 0u;
 
   // Give an initial default value to the model's vectors.
   markupProcessData.colorRuns.Reserve( DEFAULT_VECTOR_SIZE );
 
   // Give an initial default value to the model's vectors.
   markupProcessData.colorRuns.Reserve( DEFAULT_VECTOR_SIZE );
+  markupProcessData.fontRuns.Reserve( DEFAULT_VECTOR_SIZE );
 
   // Get the mark-up string buffer.
   const char* markupStringBuffer = markupString.c_str();
 
   // Get the mark-up string buffer.
   const char* markupStringBuffer = markupString.c_str();
@@ -398,10 +400,34 @@ void ProcessMarkupString( const std::string& markupString, MarkupProcessData& ma
         if( !tag.isEndTag )
         {
           // Create a new font run.
         if( !tag.isEndTag )
         {
           // Create a new font run.
+          FontDescriptionRun fontRun;
+          fontRun.characterRun.numberOfCharacters = 0u;
+
+          // Fill the run with the parameters.
+          fontRun.characterRun.characterIndex = characterIndex;
+          fontRun.slant = TextAbstraction::FontSlant::ITALIC;
+
+          fontRun.familyName = NULL;
+          fontRun.familyDefined = false;
+          fontRun.weightDefined = false;
+          fontRun.widthDefined = false;
+          fontRun.slantDefined = true;
+          fontRun.sizeDefined = false;
+
+          // Push the font run in the logical model.
+          markupProcessData.fontRuns.PushBack( fontRun );
+
+          // Push the index of the run into the stack.
+          styleStack.Push( fontRunIndex );
+
+          // Point the next free font run.
+          ++fontRunIndex;
         }
         else
         {
           // Pop the top of the stack and set the number of characters of the run.
         }
         else
         {
           // Pop the top of the stack and set the number of characters of the run.
+          FontDescriptionRun& fontRun = *( markupProcessData.fontRuns.Begin() + styleStack.Pop() );
+          fontRun.characterRun.numberOfCharacters = characterIndex - fontRun.characterRun.characterIndex;
         }
       } // <i></i>
       else if( TokenComparison( XHTML_U_TAG, tag.buffer, tag.length ) )
         }
       } // <i></i>
       else if( TokenComparison( XHTML_U_TAG, tag.buffer, tag.length ) )
@@ -420,10 +446,35 @@ void ProcessMarkupString( const std::string& markupString, MarkupProcessData& ma
         if( !tag.isEndTag )
         {
           // Create a new font run.
         if( !tag.isEndTag )
         {
           // Create a new font run.
+          FontDescriptionRun fontRun;
+          fontRun.characterRun.numberOfCharacters = 0u;
+
+          // Fill the run with the parameters.
+          fontRun.characterRun.characterIndex = characterIndex;
+
+          fontRun.weight = TextAbstraction::FontWeight::BOLD;
+
+          fontRun.familyName = NULL;
+          fontRun.familyDefined = false;
+          fontRun.weightDefined = true;
+          fontRun.widthDefined = false;
+          fontRun.slantDefined = false;
+          fontRun.sizeDefined = false;
+
+          // Push the font run in the logical model.
+          markupProcessData.fontRuns.PushBack( fontRun );
+
+          // Push the index of the run into the stack.
+          styleStack.Push( fontRunIndex );
+
+          // Point the next free font run.
+          ++fontRunIndex;
         }
         else
         {
           // Pop the top of the stack and set the number of characters of the run.
         }
         else
         {
           // Pop the top of the stack and set the number of characters of the run.
+          FontDescriptionRun& fontRun = *( markupProcessData.fontRuns.Begin() + styleStack.Pop() );
+          fontRun.characterRun.numberOfCharacters = characterIndex - fontRun.characterRun.characterIndex;
         }
       } // <b></b>
       else if( TokenComparison( XHTML_FONT_TAG, tag.buffer, tag.length ) )
         }
       } // <b></b>
       else if( TokenComparison( XHTML_FONT_TAG, tag.buffer, tag.length ) )
@@ -431,10 +482,35 @@ void ProcessMarkupString( const std::string& markupString, MarkupProcessData& ma
         if( !tag.isEndTag )
         {
           // Create a new font run.
         if( !tag.isEndTag )
         {
           // Create a new font run.
+          FontDescriptionRun fontRun;
+          fontRun.characterRun.numberOfCharacters = 0u;
+
+          // Fill the run with the parameters.
+          fontRun.characterRun.characterIndex = characterIndex;
+
+          fontRun.familyName = NULL;
+          fontRun.familyDefined = false;
+          fontRun.weightDefined = false;
+          fontRun.widthDefined = false;
+          fontRun.slantDefined = false;
+          fontRun.sizeDefined = false;
+
+          ProcessFontTag( tag, fontRun );
+
+          // Push the font run in the logical model.
+          markupProcessData.fontRuns.PushBack( fontRun );
+
+          // Push the index of the run into the stack.
+          styleStack.Push( fontRunIndex );
+
+          // Point the next free font run.
+          ++fontRunIndex;
         }
         else
         {
           // Pop the top of the stack and set the number of characters of the run.
         }
         else
         {
           // Pop the top of the stack and set the number of characters of the run.
+          FontDescriptionRun& fontRun = *( markupProcessData.fontRuns.Begin() + styleStack.Pop() );
+          fontRun.characterRun.numberOfCharacters = characterIndex - fontRun.characterRun.characterIndex;
         }
       } // <font></font>
       else if( TokenComparison( XHTML_SHADOW_TAG, tag.buffer, tag.length ) )
         }
       } // <font></font>
       else if( TokenComparison( XHTML_SHADOW_TAG, tag.buffer, tag.length ) )
@@ -510,6 +586,15 @@ void ProcessMarkupString( const std::string& markupString, MarkupProcessData& ma
   }
 
   // Resize the model's vectors.
   }
 
   // Resize the model's vectors.
+  if( 0u == fontRunIndex )
+  {
+    markupProcessData.fontRuns.Clear();
+  }
+  else
+  {
+    markupProcessData.fontRuns.Resize( fontRunIndex );
+  }
+
   if( 0u == colorRunIndex )
   {
     markupProcessData.colorRuns.Clear();
   if( 0u == colorRunIndex )
   {
     markupProcessData.colorRuns.Clear();
index 966622e..0c43300 100644 (file)
@@ -24,6 +24,7 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/color-run.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/color-run.h>
+#include <dali-toolkit/internal/text/font-description-run.h>
 
 namespace Dali
 {
 
 namespace Dali
 {
@@ -39,14 +40,17 @@ namespace Text
  */
 struct MarkupProcessData
 {
  */
 struct MarkupProcessData
 {
-  MarkupProcessData( Vector<ColorRun>& colorRuns )
+MarkupProcessData( Vector<ColorRun>& colorRuns,
+                   Vector<FontDescriptionRun>& fontRuns )
   : colorRuns( colorRuns ),
   : colorRuns( colorRuns ),
+    fontRuns( fontRuns ),
     markupProcessedText()
   {}
 
     markupProcessedText()
   {}
 
-  Vector<ColorRun>&           colorRuns;
+  Vector<ColorRun>&           colorRuns;           ///< The color runs.
+  Vector<FontDescriptionRun>& fontRuns;            ///< The font description runs.
 
 
-  std::string                 markupProcessedText;
+  std::string                 markupProcessedText; ///< The mark-up string.
 };
 
 /**
 };
 
 /**
index 37cf040..f37bdc2 100644 (file)
@@ -45,40 +45,78 @@ namespace Internal
 {
 
 /**
 {
 
 /**
- * @brief Retrieves the font Id from the font run for a given character's @p index.
+ * @brief Merges the font descriptions to retrieve the font Id for each character.
  *
  *
- * If the character's index exceeds the current font run it increases the iterator to get the next one.
- *
- * @param[in] index The character's index.
- * @param[in,out] fontRunIt Iterator to the current font run.
- * @param[in] fontRunEndIt Iterator to one after the last font run.
- *
- * @return The font id.
+ * @param[in] fontDescriptions The font descriptions.
+ * @param[out] fontIds The font id for each character.
+ * @param[in] defaultFontDescription The default font description.
+ * @param[in] defaultPointSize The default font size.
  */
  */
-FontId GetFontId( Length index,
-                  Vector<FontRun>::ConstIterator& fontRunIt,
-                  const Vector<FontRun>::ConstIterator& fontRunEndIt )
+void MergeFontDescriptions( const Vector<FontDescriptionRun>& fontDescriptions,
+                            Vector<FontId>& fontIds,
+                            const TextAbstraction::FontDescription& defaultFontDescription,
+                            TextAbstraction::PointSize26Dot6 defaultPointSize )
 {
 {
-  FontId fontId = 0u;
+  // Get the handle to the font client.
+  TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
 
 
-  if( fontRunIt != fontRunEndIt )
-  {
-    const FontRun& fontRun = *fontRunIt;
+  // Pointer to the font id buffer.
+  FontId* fontIdsBuffer = fontIds.Begin();
 
 
-    if( ( index >= fontRun.characterRun.characterIndex ) &&
-        ( index < fontRun.characterRun.characterIndex + fontRun.characterRun.numberOfCharacters ) )
+  // Traverse all the characters.
+  const Length numberOfCharacters = fontIds.Count();
+  for( CharacterIndex index = 0u; index < numberOfCharacters; ++index )
+  {
+    // The default font description and font point size.
+    TextAbstraction::FontDescription fontDescription = defaultFontDescription;
+    TextAbstraction::PointSize26Dot6 fontSize = defaultPointSize;
+    bool defaultFont = true;
+
+    // Traverse all the font descriptions.
+    for( Vector<FontDescriptionRun>::ConstIterator it = fontDescriptions.Begin(),
+           endIt = fontDescriptions.End();
+         it != endIt;
+         ++it )
     {
     {
-      fontId = fontRun.fontId;
+      // Check whether the character's font is modified by the current font description.
+      const FontDescriptionRun& fontRun = *it;
+      if( ( index >= fontRun.characterRun.characterIndex ) &&
+          ( index < fontRun.characterRun.characterIndex + fontRun.characterRun.numberOfCharacters ) )
+      {
+        if( fontRun.familyDefined )
+        {
+          fontDescription.family = std::string( fontRun.familyName, fontRun.familyLength );
+          defaultFont = false;
+        }
+        if( fontRun.weightDefined )
+        {
+          fontDescription.weight = fontRun.weight;
+          defaultFont = false;
+        }
+        if( fontRun.widthDefined )
+        {
+          fontDescription.width = fontRun.width;
+          defaultFont = false;
+        }
+        if( fontRun.slantDefined )
+        {
+          fontDescription.slant = fontRun.slant;
+          defaultFont = false;
+        }
+        if( fontRun.sizeDefined )
+        {
+          fontSize = fontRun.size;
+          defaultFont = false;
+        }
+      }
     }
 
     }
 
-    if( index + 1u == fontRun.characterRun.characterIndex + fontRun.characterRun.numberOfCharacters )
+    // Get the font id if is not the default font.
+    if( !defaultFont )
     {
     {
-      // All the characters of the current run have been traversed. Get the next one for the next iteration.
-      ++fontRunIt;
+      *( fontIdsBuffer + index ) = fontClient.GetFontId( fontDescription, fontSize );
     }
   }
     }
   }
-
-  return fontId;
 }
 
 /**
 }
 
 /**
@@ -349,8 +387,13 @@ void MultilanguageSupport::SetScripts( const Vector<Character>& text,
 
 void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
                                           const Vector<ScriptRun>& scripts,
 
 void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
                                           const Vector<ScriptRun>& scripts,
+                                          const Vector<FontDescriptionRun>& fontDescriptions,
+                                          FontId defaultFontId,
                                           Vector<FontRun>& fonts )
 {
                                           Vector<FontRun>& fonts )
 {
+  // Clear any previously validated font.
+  fonts.Clear();
+
   DALI_LOG_INFO( gLogFilter, Debug::General, "-->MultilanguageSupport::ValidateFonts\n" );
   const Length numberOfCharacters = text.Count();
 
   DALI_LOG_INFO( gLogFilter, Debug::General, "-->MultilanguageSupport::ValidateFonts\n" );
   const Length numberOfCharacters = text.Count();
 
@@ -361,11 +404,6 @@ void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
     return;
   }
 
     return;
   }
 
-  // Copy the fonts set by application developers.
-  const Length numberOfFontRuns = fonts.Count();
-  const Vector<FontRun> userSetFonts = fonts;
-  fonts.Clear();
-
   // Traverse the characters and validate/set the fonts.
 
   // Get the caches.
   // Traverse the characters and validate/set the fonts.
 
   // Get the caches.
@@ -373,33 +411,46 @@ void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
   ValidateFontsPerScript** validFontsPerScriptCacheBuffer = mValidFontsPerScriptCache.Begin();
 
   // Stores the validated font runs.
   ValidateFontsPerScript** validFontsPerScriptCacheBuffer = mValidFontsPerScriptCache.Begin();
 
   // Stores the validated font runs.
-  fonts.Reserve( numberOfFontRuns );
+  fonts.Reserve( fontDescriptions.Count() );
 
   // Initializes a validated font run.
   FontRun currentFontRun;
   currentFontRun.characterRun.characterIndex = 0u;
   currentFontRun.characterRun.numberOfCharacters = 0u;
   currentFontRun.fontId = 0u;
 
   // Initializes a validated font run.
   FontRun currentFontRun;
   currentFontRun.characterRun.characterIndex = 0u;
   currentFontRun.characterRun.numberOfCharacters = 0u;
   currentFontRun.fontId = 0u;
-  currentFontRun.isDefault = false;
 
   // Get the font client.
   TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
 
 
   // Get the font client.
   TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
 
-  // Iterators of the font and script runs.
-  Vector<FontRun>::ConstIterator fontRunIt = userSetFonts.Begin();
-  Vector<FontRun>::ConstIterator fontRunEndIt = userSetFonts.End();
+  // Get the default font description and default size.
+  TextAbstraction::FontDescription defaultFontDescription;
+  TextAbstraction::PointSize26Dot6 defaultPointSize = TextAbstraction::FontClient::DEFAULT_POINT_SIZE;
+  if( defaultFontId > 0u )
+  {
+    fontClient.GetDescription( defaultFontId, defaultFontDescription );
+    defaultPointSize = fontClient.GetPointSize( defaultFontId );
+  }
+
+  // Merge font descriptions
+  Vector<FontId> fontIds;
+  fontIds.Resize( numberOfCharacters, defaultFontId );
+  MergeFontDescriptions( fontDescriptions,
+                         fontIds,
+                         defaultFontDescription,
+                         defaultPointSize );
+
+  const Character* const textBuffer = text.Begin();
+  const FontId* const fontIdsBuffer = fontIds.Begin();
   Vector<ScriptRun>::ConstIterator scriptRunIt = scripts.Begin();
   Vector<ScriptRun>::ConstIterator scriptRunEndIt = scripts.End();
 
   for( Length index = 0u; index < numberOfCharacters; ++index )
   {
     // Get the character.
   Vector<ScriptRun>::ConstIterator scriptRunIt = scripts.Begin();
   Vector<ScriptRun>::ConstIterator scriptRunEndIt = scripts.End();
 
   for( Length index = 0u; index < numberOfCharacters; ++index )
   {
     // Get the character.
-    const Character character = *( text.Begin() + index );
+    const Character character = *( textBuffer + index );
 
     // Get the font for the character.
 
     // Get the font for the character.
-    FontId fontId = GetFontId( index,
-                               fontRunIt,
-                               fontRunEndIt );
+    FontId fontId = *( fontIdsBuffer + index );
 
     // Get the script for the character.
     Script script = GetScript( index,
 
     // Get the script for the character.
     Script script = GetScript( index,
@@ -427,92 +478,77 @@ void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
     }
 
     // Whether the font being validated is a default one not set by the user.
     }
 
     // Whether the font being validated is a default one not set by the user.
-    const bool isDefault = ( 0u == fontId );
     FontId preferredFont = fontId;
 
     FontId preferredFont = fontId;
 
-    DALI_LOG_INFO( gLogFilter,
-                   Debug::Verbose,
-                   "  Is a default font : %s\n",
-                   ( isDefault ? "true" : "false" ) );
+    // Validate if the font set by the user supports the character.
 
 
-    // The default font point size.
-    PointSize26Dot6 pointSize = TextAbstraction::FontClient::DEFAULT_POINT_SIZE;
+    // Check first in the caches.
 
 
-    if( !isDefault )
+    // The user may have set the default font. Check it. Otherwise check in the valid fonts cache.
+    if( fontId != *( defaultFontPerScriptCacheBuffer + script ) )
     {
     {
-      // Validate if the font set by the user supports the character.
-
-      // Check first in the caches.
+      // Check in the valid fonts cache.
+      ValidateFontsPerScript* validateFontsPerScript = *( validFontsPerScriptCacheBuffer + script );
 
 
-      // The user may have set the default font. Check it. Otherwise check in the valid fonts cache.
-      if( fontId != *( defaultFontPerScriptCacheBuffer + script ) )
+      if( NULL == validateFontsPerScript )
       {
       {
-        // Check in the valid fonts cache.
-        ValidateFontsPerScript* validateFontsPerScript = *( validFontsPerScriptCacheBuffer + script );
-
-        if( NULL == validateFontsPerScript )
-        {
-          validateFontsPerScript = new ValidateFontsPerScript();
+        validateFontsPerScript = new ValidateFontsPerScript();
 
 
-          *( validFontsPerScriptCacheBuffer + script ) = validateFontsPerScript;
-        }
+        *( validFontsPerScriptCacheBuffer + script ) = validateFontsPerScript;
+      }
 
 
-        if( NULL != validateFontsPerScript )
+      if( NULL != validateFontsPerScript )
+      {
+        if( !validateFontsPerScript->FindValidFont( fontId ) )
         {
         {
-          if( !validateFontsPerScript->FindValidFont( fontId ) )
-          {
-            // Use the font client to validate the font.
-            GlyphIndex glyphIndex = fontClient.GetGlyphIndex( fontId, character );
+          // Use the font client to validate the font.
+          GlyphIndex glyphIndex = fontClient.GetGlyphIndex( fontId, character );
 
 
-            // Emojis are present in many monochrome fonts; prefer color by default.
-            if( TextAbstraction::EMOJI == script &&
-                0u != glyphIndex )
+          // Emojis are present in many monochrome fonts; prefer color by default.
+          if( ( TextAbstraction::EMOJI == script ) &&
+              ( 0u != glyphIndex ) )
+          {
+            BufferImage bitmap = fontClient.CreateBitmap( fontId, glyphIndex );
+            if( bitmap &&
+                ( Pixel::BGRA8888 != bitmap.GetPixelFormat() ) )
             {
             {
-              BufferImage bitmap = fontClient.CreateBitmap( fontId, glyphIndex );
-              if( bitmap &&
-                  Pixel::BGRA8888 != bitmap.GetPixelFormat() )
-              {
-                glyphIndex = 0;
-              }
+              glyphIndex = 0u;
             }
             }
+          }
 
 
-            if( 0u == glyphIndex )
+          if( 0u == glyphIndex )
+          {
+            // The font is not valid. Set to zero and a default one will be set.
+            fontId = 0u;
+          }
+          else
+          {
+            // Add the font to the valid font cache.
+
+            //   At this point the validated font supports the given character. However, characters
+            // common for all scripts, like white spaces or new paragraph characters, need to be
+            // processed differently.
+            //
+            //   i.e. A white space can have assigned a DEVANAGARI script but the font assigned may not
+            // support none of the DEVANAGARI glyphs. This font can't be added to the cache as a valid
+            // font for the DEVANAGARI script but the COMMON one.
+            if( TextAbstraction::IsCommonScript( character ) )
             {
             {
-              // Get the point size of the current font. It will be used to get a default font id.
-              pointSize = fontClient.GetPointSize( fontId );
+              validateFontsPerScript = *( validFontsPerScriptCacheBuffer + TextAbstraction::COMMON );
 
 
-              // The font is not valid. Set to zero and a default one will be set.
-              fontId = 0u;
-            }
-            else
-            {
-              // Add the font to the valid font cache.
-
-              //   At this point the validated font supports the given character. However, characters
-              // common for all scripts, like white spaces or new paragraph characters, need to be
-              // processed differently.
-              //
-              //   i.e. A white space can have assigned a DEVANAGARI script but the font assigned may not
-              // support none of the DEVANAGARI glyphs. This font can't be added to the cache as a valid
-              // font for the DEVANAGARI script but the COMMON one.
-              if( TextAbstraction::IsCommonScript( character ) )
+              if( NULL == validateFontsPerScript )
               {
               {
-                validateFontsPerScript = *( validFontsPerScriptCacheBuffer + TextAbstraction::COMMON );
-
-                if( NULL == validateFontsPerScript )
-                {
-                  validateFontsPerScript = new ValidateFontsPerScript();
+                validateFontsPerScript = new ValidateFontsPerScript();
 
 
-                  *( validFontsPerScriptCacheBuffer + TextAbstraction::COMMON ) = validateFontsPerScript;
-                }
+                *( validFontsPerScriptCacheBuffer + TextAbstraction::COMMON ) = validateFontsPerScript;
               }
               }
-
-              validateFontsPerScript->mValidFonts.PushBack( fontId );
             }
             }
+
+            validateFontsPerScript->mValidFonts.PushBack( fontId );
           }
         }
       }
           }
         }
       }
-    } // !isDefault
+    }
 
     // The font has not been validated. Find a default one.
     if( 0u == fontId )
 
     // The font has not been validated. Find a default one.
     if( 0u == fontId )
@@ -527,7 +563,7 @@ void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
         bool preferColor = ( TextAbstraction::EMOJI == script );
 
         // Find a fallback-font.
         bool preferColor = ( TextAbstraction::EMOJI == script );
 
         // Find a fallback-font.
-        fontId = fontClient.FindFallbackFont( preferredFont, character, pointSize, preferColor );
+        fontId = fontClient.FindFallbackFont( preferredFont, character, defaultPointSize, preferColor );
 
         // If the system does not support a suitable font, fallback to Latin
         if( 0u == fontId )
 
         // If the system does not support a suitable font, fallback to Latin
         if( 0u == fontId )
@@ -536,7 +572,7 @@ void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
         }
         if( 0u == fontId )
         {
         }
         if( 0u == fontId )
         {
-          fontId = fontClient.FindDefaultFont( UTF32_A, pointSize );
+          fontId = fontClient.FindDefaultFont( UTF32_A, defaultPointSize );
         }
 
         // Cache the font.
         }
 
         // Cache the font.
@@ -559,8 +595,7 @@ void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
 
     // The font is now validated.
 
 
     // The font is now validated.
 
-    if( ( fontId != currentFontRun.fontId ) ||
-        ( isDefault != currentFontRun.isDefault ) )
+    if( fontId != currentFontRun.fontId )
     {
       // Current run needs to be stored and a new one initialized.
 
     {
       // Current run needs to be stored and a new one initialized.
 
@@ -574,7 +609,6 @@ void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
       currentFontRun.characterRun.characterIndex = currentFontRun.characterRun.characterIndex + currentFontRun.characterRun.numberOfCharacters;
       currentFontRun.characterRun.numberOfCharacters = 0u;
       currentFontRun.fontId = fontId;
       currentFontRun.characterRun.characterIndex = currentFontRun.characterRun.characterIndex + currentFontRun.characterRun.numberOfCharacters;
       currentFontRun.characterRun.numberOfCharacters = 0u;
       currentFontRun.fontId = fontId;
-      currentFontRun.isDefault = isDefault;
     }
 
     // Add one more character to the run.
     }
 
     // Add one more character to the run.
index 4dfc85c..e6105ac 100644 (file)
@@ -97,10 +97,12 @@ public:
                    Vector<ScriptRun>& scripts );
 
   /**
                    Vector<ScriptRun>& scripts );
 
   /**
-   * @copydoc Dali::MultilanguageSupport::ValidateFonts( const Vector<Character>& text, const Vector<ScriptRun>& scripts, Vector<FontRun>& fonts )
+   * @copydoc Dali::MultilanguageSupport::ValidateFonts()
    */
   void ValidateFonts( const Vector<Character>& text,
                       const Vector<ScriptRun>& scripts,
    */
   void ValidateFonts( const Vector<Character>& text,
                       const Vector<ScriptRun>& scripts,
+                      const Vector<FontDescriptionRun>& fontDescriptions,
+                      FontId defaultFontId,
                       Vector<FontRun>& fonts );
 
 private:
                       Vector<FontRun>& fonts );
 
 private:
index 46d2cb5..87e594d 100644 (file)
@@ -57,10 +57,14 @@ void MultilanguageSupport::SetScripts( const Vector<Character>& text,
 
 void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
                                           const Vector<ScriptRun>& scripts,
 
 void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
                                           const Vector<ScriptRun>& scripts,
+                                          const Vector<FontDescriptionRun>& fontDescriptions,
+                                          FontId defaultFontId,
                                           Vector<FontRun>& fonts )
 {
   GetImplementation( *this ).ValidateFonts( text,
                                             scripts,
                                           Vector<FontRun>& fonts )
 {
   GetImplementation( *this ).ValidateFonts( text,
                                             scripts,
+                                            fontDescriptions,
+                                            defaultFontId,
                                             fonts );
 }
 
                                             fonts );
 }
 
index 7e47fd2..bcbb130 100644 (file)
@@ -24,6 +24,7 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/font-run.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/font-run.h>
+#include <dali-toolkit/internal/text/font-description-run.h>
 #include <dali-toolkit/internal/text/script-run.h>
 
 namespace Dali
 #include <dali-toolkit/internal/text/script-run.h>
 
 namespace Dali
@@ -97,8 +98,6 @@ public:
   /**
    * @brief Validates the character's font of the whole text.
    *
   /**
    * @brief Validates the character's font of the whole text.
    *
-   * It may update fonts set by application developers.
-   *
    * This method ensures all characters are going to be rendered using an appropriate font. Provided a valid font
    * exists in the platform.
    *
    * This method ensures all characters are going to be rendered using an appropriate font. Provided a valid font
    * exists in the platform.
    *
@@ -109,10 +108,14 @@ public:
    *
    * @param[in] text Vector of UTF-32 characters.
    * @param[in] scripts Vector containing the script runs for the whole text.
    *
    * @param[in] text Vector of UTF-32 characters.
    * @param[in] scripts Vector containing the script runs for the whole text.
-   * @param[in,out] fonts Initially contains the fonts set by the application developers. Returns the validated fonts.
+   * @param[in] fontDescriptions The fonts set by the application developers.
+   * @param[in] defaultFontId The default font's id.
+   * @param[out] fonts The validated fonts.
    */
   void ValidateFonts( const Vector<Character>& text,
                       const Vector<ScriptRun>& scripts,
    */
   void ValidateFonts( const Vector<Character>& text,
                       const Vector<ScriptRun>& scripts,
+                      const Vector<FontDescriptionRun>& fontDescriptions,
+                      FontId defaultFontId,
                       Vector<FontRun>& fonts );
 };
 
                       Vector<FontRun>& fonts );
 };
 
index a197d32..f85d410 100644 (file)
@@ -368,17 +368,18 @@ void Controller::Impl::UpdateModel( OperationsMask operationsRequired )
 
     if( validateFonts )
     {
 
     if( validateFonts )
     {
-      if( 0u == validFonts.Count() )
-      {
-        // Copy the requested font defaults received via the property system.
-        // These may not be valid i.e. may not contain glyphs for the necessary scripts.
-        GetDefaultFonts( validFonts, numberOfCharacters );
-      }
+      // Validate the fonts set through the mark-up string.
+      Vector<FontDescriptionRun>& fontDescriptionRuns = mLogicalModel->mFontDescriptionRuns;
+
+      // Get the default font id.
+      const FontId defaultFontId = ( NULL == mFontDefaults ) ? 0u : mFontDefaults->GetFontId( mFontClient );
 
       // Validates the fonts. If there is a character with no assigned font it sets a default one.
       // After this call, fonts are validated.
       multilanguageSupport.ValidateFonts( utf32Characters,
                                           scripts,
 
       // Validates the fonts. If there is a character with no assigned font it sets a default one.
       // After this call, fonts are validated.
       multilanguageSupport.ValidateFonts( utf32Characters,
                                           scripts,
+                                          fontDescriptionRuns,
+                                          defaultFontId,
                                           validFonts );
     }
   }
                                           validFonts );
     }
   }
@@ -517,22 +518,37 @@ bool Controller::Impl::UpdateModelStyle( OperationsMask operationsRequired )
 
 void Controller::Impl::RetrieveDefaultInputStyle( InputStyle& inputStyle )
 {
 
 void Controller::Impl::RetrieveDefaultInputStyle( InputStyle& inputStyle )
 {
-  // Set the default text's color.
+  // Sets the default text's color.
   inputStyle.textColor = mTextColor;
   inputStyle.textColor = mTextColor;
-}
 
 
-void Controller::Impl::GetDefaultFonts( Vector<FontRun>& fonts, Length numberOfCharacters )
-{
+  // Sets the default font's family name, weight, width, slant and size.
   if( mFontDefaults )
   {
   if( mFontDefaults )
   {
-    DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::GetDefaultFonts font family(%s)\n", mFontDefaults->mFontDescription.family.c_str() );
-    FontRun fontRun;
-    fontRun.characterRun.characterIndex = 0;
-    fontRun.characterRun.numberOfCharacters = numberOfCharacters;
-    fontRun.fontId = mFontDefaults->GetFontId( mFontClient );
-    fontRun.isDefault = true;
+    inputStyle.familyName = mFontDefaults->mFontDescription.family;
+    inputStyle.weight = mFontDefaults->mFontDescription.weight;
+    inputStyle.width = mFontDefaults->mFontDescription.width;
+    inputStyle.slant = mFontDefaults->mFontDescription.slant;
+    inputStyle.size = mFontDefaults->mDefaultPointSize;
 
 
-    fonts.PushBack( fontRun );
+    inputStyle.familyDefined = mFontDefaults->familyDefined;
+    inputStyle.weightDefined = mFontDefaults->weightDefined;
+    inputStyle.widthDefined = mFontDefaults->widthDefined;
+    inputStyle.slantDefined = mFontDefaults->slantDefined;
+    inputStyle.sizeDefined = mFontDefaults->sizeDefined;
+  }
+  else
+  {
+    inputStyle.familyName.clear();
+    inputStyle.weight = TextAbstraction::FontWeight::NORMAL;
+    inputStyle.width = TextAbstraction::FontWidth::NORMAL;
+    inputStyle.slant = TextAbstraction::FontSlant::NORMAL;
+    inputStyle.size = 0.f;
+
+    inputStyle.familyDefined = false;
+    inputStyle.weightDefined = false;
+    inputStyle.widthDefined = false;
+    inputStyle.slantDefined = false;
+    inputStyle.sizeDefined = false;
   }
 }
 
   }
 }
 
@@ -1157,9 +1173,15 @@ void Controller::Impl::RepositionSelectionHandles()
   const Vector2 primaryPosition = primaryCursorInfo.primaryPosition + offset;
   const Vector2 secondaryPosition = secondaryCursorInfo.primaryPosition + offset;
 
   const Vector2 primaryPosition = primaryCursorInfo.primaryPosition + offset;
   const Vector2 secondaryPosition = secondaryCursorInfo.primaryPosition + offset;
 
-  mEventData->mDecorator->SetPosition( LEFT_SELECTION_HANDLE, primaryPosition.x, primaryPosition.y, primaryCursorInfo.lineHeight );
+  mEventData->mDecorator->SetPosition( LEFT_SELECTION_HANDLE,
+                                       primaryPosition.x,
+                                       primaryCursorInfo.lineOffset + offset.y,
+                                       primaryCursorInfo.lineHeight );
 
 
-  mEventData->mDecorator->SetPosition( RIGHT_SELECTION_HANDLE, secondaryPosition.x, secondaryPosition.y, secondaryCursorInfo.lineHeight );
+  mEventData->mDecorator->SetPosition( RIGHT_SELECTION_HANDLE,
+                                       secondaryPosition.x,
+                                       secondaryCursorInfo.lineOffset + offset.y,
+                                       secondaryCursorInfo.lineHeight );
 
   // Cursor to be positioned at end of selection so if selection interrupted and edit mode restarted the cursor will be at end of selection
   mEventData->mPrimaryCursorPosition = ( indicesSwapped ) ? mEventData->mLeftSelectionPosition : mEventData->mRightSelectionPosition;
 
   // Cursor to be positioned at end of selection so if selection interrupted and edit mode restarted the cursor will be at end of selection
   mEventData->mPrimaryCursorPosition = ( indicesSwapped ) ? mEventData->mLeftSelectionPosition : mEventData->mRightSelectionPosition;
@@ -1642,6 +1664,7 @@ void Controller::Impl::GetCursorPosition( CharacterIndex logical,
     // If there is no font's family set, use the default font.
     // Use the current alignment to place the cursor at the beginning, center or end of the box.
 
     // If there is no font's family set, use the default font.
     // Use the current alignment to place the cursor at the beginning, center or end of the box.
 
+    cursorInfo.lineOffset = 0.f;
     cursorInfo.lineHeight = GetDefaultFontLineHeight();
     cursorInfo.primaryCursorHeight = cursorInfo.lineHeight;
 
     cursorInfo.lineHeight = GetDefaultFontLineHeight();
     cursorInfo.primaryCursorHeight = cursorInfo.lineHeight;
 
@@ -1721,7 +1744,8 @@ void Controller::Impl::GetCursorPosition( CharacterIndex logical,
   cursorInfo.isSecondaryCursor = ( !isLastPosition && ( isCurrentRightToLeft != isNextRightToLeft ) ) ||
                                  ( isLastPosition && ( isRightToLeftParagraph != isCurrentRightToLeft ) );
 
   cursorInfo.isSecondaryCursor = ( !isLastPosition && ( isCurrentRightToLeft != isNextRightToLeft ) ) ||
                                  ( isLastPosition && ( isRightToLeftParagraph != isCurrentRightToLeft ) );
 
-  // Set the line height.
+  // Set the line offset and height.
+  cursorInfo.lineOffset = 0.f;
   cursorInfo.lineHeight = line.ascender + -line.descender;
 
   // Calculate the primary cursor.
   cursorInfo.lineHeight = line.ascender + -line.descender;
 
   // Calculate the primary cursor.
@@ -1934,7 +1958,7 @@ void Controller::Impl::UpdateCursorPosition( const CursorInfo& cursorInfo )
   // Sets the grab handle position.
   mEventData->mDecorator->SetPosition( GRAB_HANDLE,
                                        cursorPosition.x,
   // Sets the grab handle position.
   mEventData->mDecorator->SetPosition( GRAB_HANDLE,
                                        cursorPosition.x,
-                                       cursorPosition.y,
+                                       cursorInfo.lineOffset + offset.y,
                                        cursorInfo.lineHeight );
 
   if( cursorInfo.isSecondaryCursor )
                                        cursorInfo.lineHeight );
 
   if( cursorInfo.isSecondaryCursor )
@@ -1976,12 +2000,13 @@ void Controller::Impl::UpdateSelectionHandle( HandleType handleType,
     return;
   }
 
     return;
   }
 
-  const Vector2 cursorPosition = cursorInfo.primaryPosition + mEventData->mScrollPosition + mAlignmentOffset;
+  const Vector2 offset = mEventData->mScrollPosition + mAlignmentOffset;
+  const Vector2 cursorPosition = cursorInfo.primaryPosition + offset;
 
   // Sets the handle's position.
   mEventData->mDecorator->SetPosition( handleType,
                                        cursorPosition.x,
 
   // Sets the handle's position.
   mEventData->mDecorator->SetPosition( handleType,
                                        cursorPosition.x,
-                                       cursorPosition.y,
+                                       cursorInfo.lineOffset + offset.y,
                                        cursorInfo.lineHeight );
 
   // If selection handle at start of the text and other at end of the text then all text is selected.
                                        cursorInfo.lineHeight );
 
   // If selection handle at start of the text and other at end of the text then all text is selected.
index 3ae0c7f..9ee83cc 100644 (file)
@@ -81,6 +81,7 @@ struct CursorInfo
   CursorInfo()
   : primaryPosition(),
     secondaryPosition(),
   CursorInfo()
   : primaryPosition(),
     secondaryPosition(),
+    lineOffset( 0.f ),
     lineHeight( 0.f ),
     primaryCursorHeight( 0.f ),
     secondaryCursorHeight( 0.f ),
     lineHeight( 0.f ),
     primaryCursorHeight( 0.f ),
     secondaryCursorHeight( 0.f ),
@@ -92,6 +93,7 @@ struct CursorInfo
 
   Vector2 primaryPosition;       ///< The primary cursor's position.
   Vector2 secondaryPosition;     ///< The secondary cursor's position.
 
   Vector2 primaryPosition;       ///< The primary cursor's position.
   Vector2 secondaryPosition;     ///< The secondary cursor's position.
+  float   lineOffset;            ///< The vertical offset where the line containing the cursor starts.
   float   lineHeight;            ///< The height of the line where the cursor is placed.
   float   primaryCursorHeight;   ///< The primary cursor's height.
   float   secondaryCursorHeight; ///< The secondary cursor's height.
   float   lineHeight;            ///< The height of the line where the cursor is placed.
   float   primaryCursorHeight;   ///< The primary cursor's height.
   float   secondaryCursorHeight; ///< The secondary cursor's height.
@@ -187,7 +189,12 @@ struct FontDefaults
   : mFontDescription(),
     mFontStyle(),
     mDefaultPointSize( 0.f ),
   : mFontDescription(),
     mFontStyle(),
     mDefaultPointSize( 0.f ),
-    mFontId( 0u )
+    mFontId( 0u ),
+    familyDefined( false ),
+    weightDefined( false ),
+    widthDefined( false ),
+    slantDefined( false ),
+    sizeDefined( false )
   {
     // Initially use the default platform font
     TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
   {
     // Initially use the default platform font
     TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
@@ -205,10 +212,15 @@ struct FontDefaults
     return mFontId;
   }
 
     return mFontId;
   }
 
-  TextAbstraction::FontDescription mFontDescription;
-  std::string mFontStyle;
-  float mDefaultPointSize;
-  FontId mFontId;
+  TextAbstraction::FontDescription mFontDescription;  ///< The default font's description.
+  std::string                      mFontStyle;        ///< The font's style string set through the property system.
+  float                            mDefaultPointSize; ///< The default font's point size.
+  FontId                           mFontId;           ///< The font's id of the default font.
+  bool familyDefined:1; ///< Whether the default font's family name is defined.
+  bool weightDefined:1; ///< Whether the default font's weight is defined.
+  bool  widthDefined:1; ///< Whether the default font's width is defined.
+  bool  slantDefined:1; ///< Whether the default font's slant is defined.
+  bool   sizeDefined:1; ///< Whether the default font's point size is defined.
 };
 
 struct Controller::Impl
 };
 
 struct Controller::Impl
@@ -230,7 +242,6 @@ struct Controller::Impl
     mOperationsPending( NO_OPERATION ),
     mMaximumNumberOfCharacters( 50u ),
     mRecalculateNaturalSize( true ),
     mOperationsPending( NO_OPERATION ),
     mMaximumNumberOfCharacters( 50u ),
     mRecalculateNaturalSize( true ),
-    mUserDefinedFontFamily( false ),
     mMarkupProcessorEnabled( false )
   {
     mLogicalModel = LogicalModel::New();
     mMarkupProcessorEnabled( false )
   {
     mLogicalModel = LogicalModel::New();
@@ -388,14 +399,6 @@ struct Controller::Impl
   void RetrieveDefaultInputStyle( InputStyle& inputStyle );
 
   /**
   void RetrieveDefaultInputStyle( InputStyle& inputStyle );
 
   /**
-   * @brief Retrieve the default fonts.
-   *
-   * @param[out] fonts The default font family, style and point sizes.
-   * @param[in] numberOfCharacters The number of characters in the logical model.
-   */
-  void GetDefaultFonts( Dali::Vector<FontRun>& fonts, Length numberOfCharacters );
-
-  /**
    * @brief Retrieve the line height of the default font.
    */
   float GetDefaultFontLineHeight();
    * @brief Retrieve the line height of the default font.
    */
   float GetDefaultFontLineHeight();
@@ -542,7 +545,6 @@ struct Controller::Impl
   Length mMaximumNumberOfCharacters;       ///< Maximum number of characters that can be inserted.
 
   bool mRecalculateNaturalSize:1;          ///< Whether the natural size needs to be recalculated.
   Length mMaximumNumberOfCharacters;       ///< Maximum number of characters that can be inserted.
 
   bool mRecalculateNaturalSize:1;          ///< Whether the natural size needs to be recalculated.
-  bool mUserDefinedFontFamily:1;           ///< Whether the Font family was set by the user instead of being left as sytem default.
   bool mMarkupProcessorEnabled:1;          ///< Whether the mark-up procesor is enabled.
 };
 
   bool mMarkupProcessorEnabled:1;          ///< Whether the mark-up procesor is enabled.
 };
 
index f22278a..3143603 100644 (file)
@@ -20,6 +20,7 @@
 
 // EXTERNAL INCLUDES
 #include <limits>
 
 // EXTERNAL INCLUDES
 #include <limits>
+#include <memory.h>
 #include <dali/public-api/adaptor-framework/key.h>
 #include <dali/integration-api/debug.h>
 #include <dali/devel-api/adaptor-framework/clipboard-event-notifier.h>
 #include <dali/public-api/adaptor-framework/key.h>
 #include <dali/integration-api/debug.h>
 #include <dali/devel-api/adaptor-framework/clipboard-event-notifier.h>
@@ -61,6 +62,39 @@ namespace Toolkit
 namespace Text
 {
 
 namespace Text
 {
 
+/**
+ * @brief Adds a new font description run for the selected text.
+ *
+ * The new font parameters are added after the call to this method.
+ *
+ * @param[in] eventData The event data pointer.
+ * @param[in] logicalModel The logical model where to add the new font description run.
+ */
+FontDescriptionRun& UpdateSelectionFontStyleRun( EventData* eventData,
+                                                 LogicalModelPtr logicalModel )
+{
+  const bool handlesCrossed = eventData->mLeftSelectionPosition > eventData->mRightSelectionPosition;
+
+  // Get start and end position of selection
+  const CharacterIndex startOfSelectedText = handlesCrossed ? eventData->mRightSelectionPosition : eventData->mLeftSelectionPosition;
+  const Length lengthOfSelectedText = ( handlesCrossed ? eventData->mLeftSelectionPosition : eventData->mRightSelectionPosition ) - startOfSelectedText;
+
+  // Add the font run.
+  const VectorBase::SizeType numberOfRuns = logicalModel->mFontDescriptionRuns.Count();
+  logicalModel->mFontDescriptionRuns.Resize( numberOfRuns + 1u );
+
+  FontDescriptionRun& fontDescriptionRun = *( logicalModel->mFontDescriptionRuns.Begin() + numberOfRuns );
+
+  fontDescriptionRun.characterRun.characterIndex = startOfSelectedText;
+  fontDescriptionRun.characterRun.numberOfCharacters = lengthOfSelectedText;
+
+  // Recalculate the selection highlight as the metrics may have changed.
+  eventData->mUpdateLeftSelectionPosition = true;
+  eventData->mUpdateRightSelectionPosition = true;
+
+  return fontDescriptionRun;
+}
+
 ControllerPtr Controller::New( ControlInterface& controlInterface )
 {
   return ControllerPtr( new Controller( controlInterface ) );
 ControllerPtr Controller::New( ControlInterface& controlInterface )
 {
   return ControllerPtr( new Controller( controlInterface ) );
@@ -113,7 +147,8 @@ void Controller::SetText( const std::string& text )
 
   if( !text.empty() )
   {
 
   if( !text.empty() )
   {
-    MarkupProcessData markupProcessData( mImpl->mLogicalModel->mColorRuns );
+    MarkupProcessData markupProcessData( mImpl->mLogicalModel->mColorRuns,
+                                         mImpl->mLogicalModel->mFontDescriptionRuns );
 
     Length textSize = 0u;
     const uint8_t* utf8 = NULL;
 
     Length textSize = 0u;
     const uint8_t* utf8 = NULL;
@@ -269,7 +304,7 @@ void Controller::SetDefaultFontFamily( const std::string& defaultFontFamily )
 
   mImpl->mFontDefaults->mFontDescription.family = defaultFontFamily;
   DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::SetDefaultFontFamily %s\n", defaultFontFamily.c_str());
 
   mImpl->mFontDefaults->mFontDescription.family = defaultFontFamily;
   DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::SetDefaultFontFamily %s\n", defaultFontFamily.c_str());
-  mImpl->mUserDefinedFontFamily = true;
+  mImpl->mFontDefaults->familyDefined = true;
 
   // Clear the font-specific data
   ClearFontData();
 
   // Clear the font-specific data
   ClearFontData();
@@ -310,14 +345,15 @@ const std::string& Controller::GetDefaultFontStyle() const
   return EMPTY_STRING;
 }
 
   return EMPTY_STRING;
 }
 
-void Controller::SetDefaultFontWidth( FontWidth width )
+void Controller::SetDefaultFontWeight( FontWeight weight )
 {
   if( NULL == mImpl->mFontDefaults )
   {
     mImpl->mFontDefaults = new FontDefaults();
   }
 
 {
   if( NULL == mImpl->mFontDefaults )
   {
     mImpl->mFontDefaults = new FontDefaults();
   }
 
-  mImpl->mFontDefaults->mFontDescription.width = width;
+  mImpl->mFontDefaults->mFontDescription.weight = weight;
+  mImpl->mFontDefaults->weightDefined = true;
 
   // Clear the font-specific data
   ClearFontData();
 
   // Clear the font-specific data
   ClearFontData();
@@ -328,24 +364,25 @@ void Controller::SetDefaultFontWidth( FontWidth width )
   mImpl->RequestRelayout();
 }
 
   mImpl->RequestRelayout();
 }
 
-FontWidth Controller::GetDefaultFontWidth() const
+FontWeight Controller::GetDefaultFontWeight() const
 {
   if( NULL != mImpl->mFontDefaults )
   {
 {
   if( NULL != mImpl->mFontDefaults )
   {
-    return mImpl->mFontDefaults->mFontDescription.width;
+    return mImpl->mFontDefaults->mFontDescription.weight;
   }
 
   }
 
-  return TextAbstraction::FontWidth::NORMAL;
+  return TextAbstraction::FontWeight::NORMAL;
 }
 
 }
 
-void Controller::SetDefaultFontWeight( FontWeight weight )
+void Controller::SetDefaultFontWidth( FontWidth width )
 {
   if( NULL == mImpl->mFontDefaults )
   {
     mImpl->mFontDefaults = new FontDefaults();
   }
 
 {
   if( NULL == mImpl->mFontDefaults )
   {
     mImpl->mFontDefaults = new FontDefaults();
   }
 
-  mImpl->mFontDefaults->mFontDescription.weight = weight;
+  mImpl->mFontDefaults->mFontDescription.width = width;
+  mImpl->mFontDefaults->widthDefined = true;
 
   // Clear the font-specific data
   ClearFontData();
 
   // Clear the font-specific data
   ClearFontData();
@@ -356,14 +393,14 @@ void Controller::SetDefaultFontWeight( FontWeight weight )
   mImpl->RequestRelayout();
 }
 
   mImpl->RequestRelayout();
 }
 
-FontWeight Controller::GetDefaultFontWeight() const
+FontWidth Controller::GetDefaultFontWidth() const
 {
   if( NULL != mImpl->mFontDefaults )
   {
 {
   if( NULL != mImpl->mFontDefaults )
   {
-    return mImpl->mFontDefaults->mFontDescription.weight;
+    return mImpl->mFontDefaults->mFontDescription.width;
   }
 
   }
 
-  return TextAbstraction::FontWeight::NORMAL;
+  return TextAbstraction::FontWidth::NORMAL;
 }
 
 void Controller::SetDefaultFontSlant( FontSlant slant )
 }
 
 void Controller::SetDefaultFontSlant( FontSlant slant )
@@ -374,6 +411,7 @@ void Controller::SetDefaultFontSlant( FontSlant slant )
   }
 
   mImpl->mFontDefaults->mFontDescription.slant = slant;
   }
 
   mImpl->mFontDefaults->mFontDescription.slant = slant;
+  mImpl->mFontDefaults->slantDefined = true;
 
   // Clear the font-specific data
   ClearFontData();
 
   // Clear the font-specific data
   ClearFontData();
@@ -402,6 +440,7 @@ void Controller::SetDefaultPointSize( float pointSize )
   }
 
   mImpl->mFontDefaults->mDefaultPointSize = pointSize;
   }
 
   mImpl->mFontDefaults->mDefaultPointSize = pointSize;
+  mImpl->mFontDefaults->sizeDefined = true;
 
   unsigned int horizontalDpi( 0u );
   unsigned int verticalDpi( 0u );
 
   unsigned int horizontalDpi( 0u );
   unsigned int verticalDpi( 0u );
@@ -435,7 +474,7 @@ void Controller::UpdateAfterFontChange( std::string& newDefaultFont )
 {
   DALI_LOG_INFO( gLogFilter, Debug::Concise, "Controller::UpdateAfterFontChange");
 
 {
   DALI_LOG_INFO( gLogFilter, Debug::Concise, "Controller::UpdateAfterFontChange");
 
-  if( !mImpl->mUserDefinedFontFamily ) // If user defined font then should not update when system font changes
+  if( !mImpl->mFontDefaults->familyDefined ) // If user defined font then should not update when system font changes
   {
     DALI_LOG_INFO( gLogFilter, Debug::Concise, "Controller::UpdateAfterFontChange newDefaultFont(%s)\n", newDefaultFont.c_str() );
     ClearFontData();
   {
     DALI_LOG_INFO( gLogFilter, Debug::Concise, "Controller::UpdateAfterFontChange newDefaultFont(%s)\n", newDefaultFont.c_str() );
     ClearFontData();
@@ -651,6 +690,220 @@ const Vector4& Controller::GetInputColor() const
 
 }
 
 
 }
 
+void Controller::SetInputFontFamily( const std::string& fontFamily )
+{
+  if( NULL != mImpl->mEventData )
+  {
+    mImpl->mEventData->mInputStyle.familyName = fontFamily;
+    mImpl->mEventData->mInputStyle.familyDefined = true;
+
+    if( EventData::SELECTING == mImpl->mEventData->mState )
+    {
+      FontDescriptionRun& fontDescriptionRun = UpdateSelectionFontStyleRun( mImpl->mEventData,
+                                                                            mImpl->mLogicalModel );
+
+      fontDescriptionRun.familyLength = fontFamily.size();
+      fontDescriptionRun.familyName = new char[fontDescriptionRun.familyLength];
+      memcpy( fontDescriptionRun.familyName, fontFamily.c_str(), fontDescriptionRun.familyLength );
+      fontDescriptionRun.familyDefined = true;
+
+      // The memory allocated for the font family name is freed when the font description is removed from the logical model.
+
+      // Request to relayout.
+      mImpl->mOperationsPending = ALL_OPERATIONS;
+      mImpl->mRecalculateNaturalSize = true;
+      mImpl->RequestRelayout();
+
+      // As the font changes, recalculate the handle positions is needed.
+      mImpl->mEventData->mUpdateLeftSelectionPosition = true;
+      mImpl->mEventData->mUpdateRightSelectionPosition = true;
+      mImpl->mEventData->mScrollAfterUpdatePosition = true;
+    }
+  }
+}
+
+const std::string& Controller::GetInputFontFamily() const
+{
+  if( NULL != mImpl->mEventData )
+  {
+    return mImpl->mEventData->mInputStyle.familyName;
+  }
+
+  // Return the default font's family if there is no EventData.
+  return GetDefaultFontFamily();
+}
+
+void Controller::SetInputFontStyle( const std::string& fontStyle )
+{
+  if( NULL != mImpl->mEventData )
+  {
+    mImpl->mEventData->mInputStyle.fontStyle = fontStyle;
+  }
+}
+
+const std::string& Controller::GetInputFontStyle() const
+{
+  if( NULL != mImpl->mEventData )
+  {
+    return mImpl->mEventData->mInputStyle.fontStyle;
+  }
+
+  // Return the default font's style if there is no EventData.
+  return GetDefaultFontStyle();
+}
+
+void Controller::SetInputFontWeight( FontWeight weight )
+{
+  if( NULL != mImpl->mEventData )
+  {
+    mImpl->mEventData->mInputStyle.weight = weight;
+    mImpl->mEventData->mInputStyle.weightDefined = true;
+
+    if( EventData::SELECTING == mImpl->mEventData->mState )
+    {
+      FontDescriptionRun& fontDescriptionRun = UpdateSelectionFontStyleRun( mImpl->mEventData,
+                                                                            mImpl->mLogicalModel );
+
+      fontDescriptionRun.weight = weight;
+      fontDescriptionRun.weightDefined = true;
+
+      // Request to relayout.
+      mImpl->mOperationsPending = ALL_OPERATIONS;
+      mImpl->mRecalculateNaturalSize = true;
+      mImpl->RequestRelayout();
+
+      // As the font might change, recalculate the handle positions is needed.
+      mImpl->mEventData->mUpdateLeftSelectionPosition = true;
+      mImpl->mEventData->mUpdateRightSelectionPosition = true;
+      mImpl->mEventData->mScrollAfterUpdatePosition = true;
+    }
+  }
+}
+
+FontWeight Controller::GetInputFontWeight() const
+{
+  if( NULL != mImpl->mEventData )
+  {
+    return mImpl->mEventData->mInputStyle.weight;
+  }
+
+  return GetDefaultFontWeight();
+}
+
+void Controller::SetInputFontWidth( FontWidth width )
+{
+  if( NULL != mImpl->mEventData )
+  {
+    mImpl->mEventData->mInputStyle.width = width;
+    mImpl->mEventData->mInputStyle.widthDefined = true;
+
+    if( EventData::SELECTING == mImpl->mEventData->mState )
+    {
+      FontDescriptionRun& fontDescriptionRun = UpdateSelectionFontStyleRun( mImpl->mEventData,
+                                                                            mImpl->mLogicalModel );
+
+      fontDescriptionRun.width = width;
+      fontDescriptionRun.widthDefined = true;
+
+      // Request to relayout.
+      mImpl->mOperationsPending = ALL_OPERATIONS;
+      mImpl->mRecalculateNaturalSize = true;
+      mImpl->RequestRelayout();
+
+      // As the font might change, recalculate the handle positions is needed.
+      mImpl->mEventData->mUpdateLeftSelectionPosition = true;
+      mImpl->mEventData->mUpdateRightSelectionPosition = true;
+      mImpl->mEventData->mScrollAfterUpdatePosition = true;
+    }
+  }
+}
+
+FontWidth Controller::GetInputFontWidth() const
+{
+  if( NULL != mImpl->mEventData )
+  {
+    return mImpl->mEventData->mInputStyle.width;
+  }
+
+  return GetDefaultFontWidth();
+}
+
+void Controller::SetInputFontSlant( FontSlant slant )
+{
+  if( NULL != mImpl->mEventData )
+  {
+    mImpl->mEventData->mInputStyle.slant = slant;
+    mImpl->mEventData->mInputStyle.slantDefined = true;
+
+    if( EventData::SELECTING == mImpl->mEventData->mState )
+    {
+      FontDescriptionRun& fontDescriptionRun = UpdateSelectionFontStyleRun( mImpl->mEventData,
+                                                                            mImpl->mLogicalModel );
+
+      fontDescriptionRun.slant = slant;
+      fontDescriptionRun.slantDefined = true;
+
+      // Request to relayout.
+      mImpl->mOperationsPending = ALL_OPERATIONS;
+      mImpl->mRecalculateNaturalSize = true;
+      mImpl->RequestRelayout();
+
+      // As the font might change, recalculate the handle positions is needed.
+      mImpl->mEventData->mUpdateLeftSelectionPosition = true;
+      mImpl->mEventData->mUpdateRightSelectionPosition = true;
+      mImpl->mEventData->mScrollAfterUpdatePosition = true;
+    }
+  }
+}
+
+FontSlant Controller::GetInputFontSlant() const
+{
+  if( NULL != mImpl->mEventData )
+  {
+    return mImpl->mEventData->mInputStyle.slant;
+  }
+
+  return GetDefaultFontSlant();
+}
+
+void Controller::SetInputFontPointSize( float size )
+{
+  if( NULL != mImpl->mEventData )
+  {
+    mImpl->mEventData->mInputStyle.size = size;
+
+    if( EventData::SELECTING == mImpl->mEventData->mState )
+    {
+      FontDescriptionRun& fontDescriptionRun = UpdateSelectionFontStyleRun( mImpl->mEventData,
+                                                                            mImpl->mLogicalModel );
+
+      fontDescriptionRun.size = static_cast<PointSize26Dot6>( size * 64.f );
+      fontDescriptionRun.sizeDefined = true;
+
+      // Request to relayout.
+      mImpl->mOperationsPending = ALL_OPERATIONS;
+      mImpl->mRecalculateNaturalSize = true;
+      mImpl->RequestRelayout();
+
+      // As the font might change, recalculate the handle positions is needed.
+      mImpl->mEventData->mUpdateLeftSelectionPosition = true;
+      mImpl->mEventData->mUpdateRightSelectionPosition = true;
+      mImpl->mEventData->mScrollAfterUpdatePosition = true;
+    }
+  }
+}
+
+float Controller::GetInputFontPointSize() const
+{
+  if( NULL != mImpl->mEventData )
+  {
+    return mImpl->mEventData->mInputStyle.size;
+  }
+
+  // Return the default font's point size if there is no EventData.
+  return GetDefaultPointSize();
+}
+
 void Controller::SetEnableCursorBlink( bool enable )
 {
   DALI_ASSERT_DEBUG( NULL != mImpl->mEventData && "TextInput disabled" );
 void Controller::SetEnableCursorBlink( bool enable )
 {
   DALI_ASSERT_DEBUG( NULL != mImpl->mEventData && "TextInput disabled" );
@@ -1564,7 +1817,9 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ
     // The cursor position.
     CharacterIndex& cursorIndex = mImpl->mEventData->mPrimaryCursorPosition;
 
     // The cursor position.
     CharacterIndex& cursorIndex = mImpl->mEventData->mPrimaryCursorPosition;
 
-    // Updates the text style runs.
+    // Update the text's style.
+
+    // Updates the text style runs by adding characters.
     mImpl->mLogicalModel->UpdateTextStyleRuns( cursorIndex, maxSizeOfNewText );
 
     // Get the character index from the cursor index.
     mImpl->mLogicalModel->UpdateTextStyleRuns( cursorIndex, maxSizeOfNewText );
 
     // Get the character index from the cursor index.
@@ -1577,6 +1832,13 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ
     // Whether to add a new text color run.
     const bool addColorRun = style.textColor != mImpl->mEventData->mInputStyle.textColor;
 
     // Whether to add a new text color run.
     const bool addColorRun = style.textColor != mImpl->mEventData->mInputStyle.textColor;
 
+    // Whether to add a new font run.
+    const bool addFontNameRun = style.familyName != mImpl->mEventData->mInputStyle.familyName;
+    const bool addFontWeightRun = style.weight != mImpl->mEventData->mInputStyle.weight;
+    const bool addFontWidthRun = style.width != mImpl->mEventData->mInputStyle.width;
+    const bool addFontSlantRun = style.slant != mImpl->mEventData->mInputStyle.slant;
+    const bool addFontSizeRun = style.size != mImpl->mEventData->mInputStyle.size;
+
     // Add style runs.
     if( addColorRun )
     {
     // Add style runs.
     if( addColorRun )
     {
@@ -1589,6 +1851,55 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ
       colorRun.characterRun.numberOfCharacters = maxSizeOfNewText;
     }
 
       colorRun.characterRun.numberOfCharacters = maxSizeOfNewText;
     }
 
+    if( addFontNameRun   ||
+        addFontWeightRun ||
+        addFontWidthRun  ||
+        addFontSlantRun  ||
+        addFontSizeRun )
+    {
+      const VectorBase::SizeType numberOfRuns = mImpl->mLogicalModel->mFontDescriptionRuns.Count();
+      mImpl->mLogicalModel->mFontDescriptionRuns.Resize( numberOfRuns + 1u );
+
+      FontDescriptionRun& fontDescriptionRun = *( mImpl->mLogicalModel->mFontDescriptionRuns.Begin() + numberOfRuns );
+
+      if( addFontNameRun )
+      {
+        fontDescriptionRun.familyLength = mImpl->mEventData->mInputStyle.familyName.size();
+        fontDescriptionRun.familyName = new char[fontDescriptionRun.familyLength];
+        memcpy( fontDescriptionRun.familyName, mImpl->mEventData->mInputStyle.familyName.c_str(), fontDescriptionRun.familyLength );
+        fontDescriptionRun.familyDefined = true;
+
+        // The memory allocated for the font family name is freed when the font description is removed from the logical model.
+      }
+
+      if( addFontWeightRun )
+      {
+        fontDescriptionRun.weight = mImpl->mEventData->mInputStyle.weight;
+        fontDescriptionRun.weightDefined = true;
+      }
+
+      if( addFontWidthRun )
+      {
+        fontDescriptionRun.width = mImpl->mEventData->mInputStyle.width;
+        fontDescriptionRun.widthDefined = true;
+      }
+
+      if( addFontSlantRun )
+      {
+        fontDescriptionRun.slant = mImpl->mEventData->mInputStyle.slant;
+        fontDescriptionRun.slantDefined = true;
+      }
+
+      if( addFontSizeRun )
+      {
+        fontDescriptionRun.size = static_cast<PointSize26Dot6>( mImpl->mEventData->mInputStyle.size * 64.f );
+        fontDescriptionRun.sizeDefined = true;
+      }
+
+      fontDescriptionRun.characterRun.characterIndex = cursorIndex;
+      fontDescriptionRun.characterRun.numberOfCharacters = maxSizeOfNewText;
+    }
+
     // Insert at current cursor position.
     Vector<Character>& modifyText = mImpl->mLogicalModel->mText;
 
     // Insert at current cursor position.
     Vector<Character>& modifyText = mImpl->mLogicalModel->mText;
 
@@ -2228,6 +2539,7 @@ void Controller::ClearFontData()
 void Controller::ClearStyleData()
 {
   mImpl->mLogicalModel->mColorRuns.Clear();
 void Controller::ClearStyleData()
 {
   mImpl->mLogicalModel->mColorRuns.Clear();
+  mImpl->mLogicalModel->ClearFontDescriptionRuns();
 }
 
 Controller::Controller( ControlInterface& controlInterface )
 }
 
 Controller::Controller( ControlInterface& controlInterface )
index 058719e..a9cc0df 100644 (file)
@@ -224,32 +224,32 @@ public:
   const std::string& GetDefaultFontStyle() const;
 
   /**
   const std::string& GetDefaultFontStyle() const;
 
   /**
-   * @brief Sets the default font width.
+   * @brief Sets the default font weight.
    *
    *
-   * @param[in] width The font width.
+   * @param[in] weight The font weight.
    */
    */
-  void SetDefaultFontWidth( FontWidth width );
+  void SetDefaultFontWeight( FontWeight weight );
 
   /**
 
   /**
-   * @brief Retrieves the default font width.
+   * @brief Retrieves the default font weight.
    *
    *
-   * @return The default font width.
+   * @return The default font weight.
    */
    */
-  FontWidth GetDefaultFontWidth() const;
+  FontWeight GetDefaultFontWeight() const;
 
   /**
 
   /**
-   * @brief Sets the default font weight.
+   * @brief Sets the default font width.
    *
    *
-   * @param[in] weight The font weight.
+   * @param[in] width The font width.
    */
    */
-  void SetDefaultFontWeight( FontWeight weight );
+  void SetDefaultFontWidth( FontWidth width );
 
   /**
 
   /**
-   * @brief Retrieves the default font weight.
+   * @brief Retrieves the default font width.
    *
    *
-   * @return The default font weight.
+   * @return The default font width.
    */
    */
-  FontWeight GetDefaultFontWeight() const;
+  FontWidth GetDefaultFontWidth() const;
 
   /**
    * @brief Sets the default font slant.
 
   /**
    * @brief Sets the default font slant.
@@ -398,6 +398,90 @@ public:
   const Vector4& GetInputColor() const;
 
   /**
   const Vector4& GetInputColor() const;
 
   /**
+   * @brief Sets the input text's font family name.
+   *
+   * @param[in] fontFamily The text's font family name.
+   */
+  void SetInputFontFamily( const std::string& fontFamily );
+
+  /**
+   * @brief Retrieves the input text's font family name.
+   *
+   * @return The input text's font family name.
+   */
+  const std::string& GetInputFontFamily() const;
+
+  /**
+   * @brief Sets the input text's font style.
+   *
+   * @param[in] fontStyle The input text's font style.
+   */
+  void SetInputFontStyle( const std::string& fontStyle );
+
+  /**
+   * @brief Retrieves the input text's font style.
+   *
+   * @return The input text's font style.
+   */
+  const std::string& GetInputFontStyle() const;
+
+  /**
+   * @brief Sets the input font's weight.
+   *
+   * @param[in] weight The input font's weight.
+   */
+  void SetInputFontWeight( FontWeight weight );
+
+  /**
+   * @brief Retrieves the input font's weight.
+   *
+   * @return The input font's weight.
+   */
+  FontWeight GetInputFontWeight() const;
+
+  /**
+   * @brief Sets the input font's width.
+   *
+   * @param[in] width The input font's width.
+   */
+  void SetInputFontWidth( FontWidth width );
+
+  /**
+   * @brief Retrieves the input font's width.
+   *
+   * @return The input font's width.
+   */
+  FontWidth GetInputFontWidth() const;
+
+  /**
+   * @brief Sets the input font's slant.
+   *
+   * @param[in] slant The input font's slant.
+   */
+  void SetInputFontSlant( FontSlant slant );
+
+  /**
+   * @brief Retrieves the input font's slant.
+   *
+   * @return The input font's slant.
+   */
+  FontSlant GetInputFontSlant() const;
+
+  /**
+   * @brief Sets the input font's point size.
+   *
+   * @param[in] size The input font's point size.
+   */
+  void SetInputFontPointSize( float size );
+
+  /**
+   * @brief Retrieves the input font's point size.
+   *
+   * @return The input font's point size.
+   */
+  float GetInputFontPointSize() const;
+
+  /**
    * @brief Called to enable/disable cursor blink.
    *
    * @note Only editable controls should calls this.
    * @brief Called to enable/disable cursor blink.
    *
    * @note Only editable controls should calls this.
diff --git a/dali-toolkit/internal/text/text-font-style.cpp b/dali-toolkit/internal/text/text-font-style.cpp
new file mode 100644 (file)
index 0000000..681ffc7
--- /dev/null
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// FILE HEADER
+#include <dali-toolkit/internal/text/text-font-style.h>
+
+// EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/builder/json-parser.h>
+#include <dali-toolkit/devel-api/builder/tree-node.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+namespace
+{
+const std::string STYLE_KEY( "style" );
+const std::string WEIGHT_KEY( "weight" );
+const std::string WIDTH_KEY( "width" );
+const std::string SLANT_KEY( "slant" );
+const std::string EMPTY_STRING( "" );
+
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_CONTROLS");
+#endif
+
+} // namespace
+
+/**
+ * @brief Creates a map with pairs 'key,value' with the font's style parameters.
+ *
+ * @param[in] node Data structure with the font's style parameters.
+ * @param[out] map A map with the font's style parameters.
+ *
+ */
+void CreateFontStyleMap( const TreeNode* const node, Property::Map& map )
+{
+  switch( node->GetType() )
+  {
+    case TreeNode::IS_NULL:
+    case TreeNode::OBJECT:
+    case TreeNode::ARRAY: // FALL THROUGH
+    {
+      break;
+    }
+    case TreeNode::STRING:
+    {
+      map.Insert( node->GetName(), Property::Value( node->GetString() ) );
+      break;
+    }
+    case TreeNode::INTEGER:
+    case TreeNode::FLOAT:
+    case TreeNode::BOOLEAN: // FALL THROUGH
+    {
+      break;
+    }
+  }
+
+  for( TreeNode::ConstIterator it = node->CBegin(), endIt = node->CEnd(); it != endIt; ++it )
+  {
+    const TreeNode::KeyNodePair& pair = *it;
+    CreateFontStyleMap( &pair.second, map );
+  }
+}
+
+/**
+ * @brief Parses the font's style string.
+ *
+ * @param[in] style The font's style string.
+ * @param[out] map A map with the font's style parameters.
+ *
+ */
+void ParseFontStyleString( const std::string& style, Property::Map& map )
+{
+  Toolkit::JsonParser parser = Toolkit::JsonParser::New();
+
+  if( parser.Parse( style ) )
+  {
+    const TreeNode* const node = parser.GetRoot();
+
+    CreateFontStyleMap( node, map );
+  }
+}
+
+void SetFontStyleProperty( ControllerPtr controller, const Property::Value& value, FontStyle::Type type )
+{
+  if( controller )
+  {
+    const std::string style = value.Get< std::string >();
+    DALI_LOG_INFO( gLogFilter, Debug::General, "Text Control %p FONT_STYLE %s\n", controller.Get(), style.c_str() );
+
+    switch( type )
+    {
+      case FontStyle::DEFAULT:
+      {
+        // Stores the default font's style string to be recovered by the GetFontStyleProperty() function.
+        controller->SetDefaultFontStyle( style );
+        break;
+      }
+      case FontStyle::INPUT:
+      {
+        // Stores the input font's style string to be recovered by the GetFontStyleProperty() function.
+        controller->SetInputFontStyle( style );
+        break;
+      }
+    }
+
+    // Parses and applies the style.
+    Property::Map map;
+    ParseFontStyleString( style, map );
+
+    if( !map.Empty() )
+    {
+      /// Weight key
+      Property::Value* weightValue = map.Find( WEIGHT_KEY );
+
+      FontWeight weight = TextAbstraction::FontWeight::NORMAL;
+      const bool weightDefined = weightValue != NULL;
+      if( weightDefined )
+      {
+        const std::string weightStr = weightValue->Get<std::string>();
+
+        Scripting::GetEnumeration< FontWeight >( weightStr.c_str(),
+                                                 FONT_WEIGHT_STRING_TABLE,
+                                                 FONT_WEIGHT_STRING_TABLE_COUNT,
+                                                 weight );
+      }
+
+      /// Width key
+      Property::Value* widthValue = map.Find( WIDTH_KEY );
+
+      FontWidth width = TextAbstraction::FontWidth::NORMAL;
+      const bool widthDefined = widthValue != NULL;
+      if( widthDefined )
+      {
+        const std::string widthStr = widthValue->Get<std::string>();
+
+        Scripting::GetEnumeration< FontWidth >( widthStr.c_str(),
+                                                FONT_WIDTH_STRING_TABLE,
+                                                FONT_WIDTH_STRING_TABLE_COUNT,
+                                                width );
+      }
+
+      /// Slant key
+      Property::Value* slantValue = map.Find( SLANT_KEY );
+
+      FontSlant slant = TextAbstraction::FontSlant::NORMAL;
+      const bool slantDefined = slantValue != NULL;
+      if( slantDefined )
+      {
+        const std::string slantStr = slantValue->Get<std::string>();
+
+        Scripting::GetEnumeration< FontSlant >( slantStr.c_str(),
+                                                FONT_SLANT_STRING_TABLE,
+                                                FONT_SLANT_STRING_TABLE_COUNT,
+                                                slant );
+      }
+
+      switch( type )
+      {
+        case FontStyle::DEFAULT:
+        {
+          // Sets the default font's style values.
+          if( weightDefined && ( controller->GetDefaultFontWeight() != weight ) )
+          {
+            controller->SetDefaultFontWeight( weight );
+          }
+
+          if( widthDefined && ( controller->GetDefaultFontWidth() != width ) )
+          {
+            controller->SetDefaultFontWidth( width );
+          }
+
+          if( slantDefined && ( controller->GetDefaultFontSlant() != slant ) )
+          {
+            controller->SetDefaultFontSlant( slant );
+          }
+          break;
+        }
+        case FontStyle::INPUT:
+        {
+          // Sets the input font's style values.
+          if( weightDefined && ( controller->GetInputFontWeight() != weight ) )
+          {
+            controller->SetInputFontWeight( weight );
+          }
+
+          if( widthDefined && ( controller->GetInputFontWidth() != width ) )
+          {
+            controller->SetInputFontWidth( width );
+          }
+
+          if( slantDefined && ( controller->GetInputFontSlant() != slant ) )
+          {
+            controller->SetInputFontSlant( slant );
+          }
+          break;
+        }
+      }
+    }
+  }
+}
+
+void GetFontStyleProperty( ControllerPtr controller, Property::Value& value, FontStyle::Type type )
+{
+  if( controller )
+  {
+    switch( type )
+    {
+      case FontStyle::DEFAULT:
+      {
+        value = controller->GetDefaultFontStyle();
+        break;
+      }
+      case FontStyle::INPUT:
+      {
+        value = controller->GetInputFontStyle();
+        break;
+      }
+    }
+  }
+}
+
+FontWeight StringToWeight( const char* const weightStr )
+{
+  FontWeight weight = TextAbstraction::FontWeight::NORMAL;
+  Scripting::GetEnumeration<FontWeight>( weightStr,
+                                         FONT_WEIGHT_STRING_TABLE,
+                                         FONT_WEIGHT_STRING_TABLE_COUNT,
+                                         weight );
+
+  return weight;
+}
+
+FontWidth StringToWidth( const char* const widthStr )
+{
+  FontWidth width = TextAbstraction::FontWidth::NORMAL;
+  Scripting::GetEnumeration<FontWidth>( widthStr,
+                                        FONT_WIDTH_STRING_TABLE,
+                                        FONT_WIDTH_STRING_TABLE_COUNT,
+                                        width );
+
+  return width;
+}
+
+FontSlant StringToSlant( const char* const slantStr )
+{
+  FontSlant slant = TextAbstraction::FontSlant::NORMAL;
+  Scripting::GetEnumeration<FontSlant>( slantStr,
+                                        FONT_SLANT_STRING_TABLE,
+                                        FONT_SLANT_STRING_TABLE_COUNT,
+                                        slant );
+
+  return slant;
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
@@ -2,7 +2,7 @@
 #define __DALI_TOOLKIT_INTERNAL_TEXT_FONT_STYLE_H__
 
 /*
 #define __DALI_TOOLKIT_INTERNAL_TEXT_FONT_STYLE_H__
 
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -34,20 +34,6 @@ namespace Toolkit
 namespace Text
 {
 
 namespace Text
 {
 
-const Scripting::StringEnum FONT_WIDTH_STRING_TABLE[] =
-{
-  { "ultraCondensed", TextAbstraction::FontWidth::ULTRA_CONDENSED },
-  { "extraCondensed", TextAbstraction::FontWidth::EXTRA_CONDENSED },
-  { "condensed", TextAbstraction::FontWidth::CONDENSED },
-  { "semiCondensed", TextAbstraction::FontWidth::SEMI_CONDENSED },
-  { "normal", TextAbstraction::FontWidth::NORMAL },
-  { "semiExpanded", TextAbstraction::FontWidth::SEMI_EXPANDED },
-  { "expanded", TextAbstraction::FontWidth::EXPANDED },
-  { "extraExpanded", TextAbstraction::FontWidth::EXTRA_EXPANDED },
-  { "ultraExpanded", TextAbstraction::FontWidth::ULTRA_EXPANDED },
-};
-const unsigned int FONT_WIDTH_STRING_TABLE_COUNT = sizeof( FONT_WIDTH_STRING_TABLE ) / sizeof( FONT_WIDTH_STRING_TABLE[0] );
-
 const Scripting::StringEnum FONT_WEIGHT_STRING_TABLE[] =
 {
   { "thin", TextAbstraction::FontWeight::THIN },
 const Scripting::StringEnum FONT_WEIGHT_STRING_TABLE[] =
 {
   { "thin", TextAbstraction::FontWeight::THIN },
@@ -71,6 +57,20 @@ const Scripting::StringEnum FONT_WEIGHT_STRING_TABLE[] =
 };
 const unsigned int FONT_WEIGHT_STRING_TABLE_COUNT = sizeof( FONT_WEIGHT_STRING_TABLE ) / sizeof( FONT_WEIGHT_STRING_TABLE[0] );
 
 };
 const unsigned int FONT_WEIGHT_STRING_TABLE_COUNT = sizeof( FONT_WEIGHT_STRING_TABLE ) / sizeof( FONT_WEIGHT_STRING_TABLE[0] );
 
+const Scripting::StringEnum FONT_WIDTH_STRING_TABLE[] =
+{
+  { "ultraCondensed", TextAbstraction::FontWidth::ULTRA_CONDENSED },
+  { "extraCondensed", TextAbstraction::FontWidth::EXTRA_CONDENSED },
+  { "condensed", TextAbstraction::FontWidth::CONDENSED },
+  { "semiCondensed", TextAbstraction::FontWidth::SEMI_CONDENSED },
+  { "normal", TextAbstraction::FontWidth::NORMAL },
+  { "semiExpanded", TextAbstraction::FontWidth::SEMI_EXPANDED },
+  { "expanded", TextAbstraction::FontWidth::EXPANDED },
+  { "extraExpanded", TextAbstraction::FontWidth::EXTRA_EXPANDED },
+  { "ultraExpanded", TextAbstraction::FontWidth::ULTRA_EXPANDED },
+};
+const unsigned int FONT_WIDTH_STRING_TABLE_COUNT = sizeof( FONT_WIDTH_STRING_TABLE ) / sizeof( FONT_WIDTH_STRING_TABLE[0] );
+
 const Scripting::StringEnum FONT_SLANT_STRING_TABLE[] =
 {
   { "normal", TextAbstraction::FontSlant::NORMAL },
 const Scripting::StringEnum FONT_SLANT_STRING_TABLE[] =
 {
   { "normal", TextAbstraction::FontSlant::NORMAL },
@@ -80,6 +80,15 @@ const Scripting::StringEnum FONT_SLANT_STRING_TABLE[] =
 };
 const unsigned int FONT_SLANT_STRING_TABLE_COUNT = sizeof( FONT_SLANT_STRING_TABLE ) / sizeof( FONT_SLANT_STRING_TABLE[0] );
 
 };
 const unsigned int FONT_SLANT_STRING_TABLE_COUNT = sizeof( FONT_SLANT_STRING_TABLE ) / sizeof( FONT_SLANT_STRING_TABLE[0] );
 
+namespace FontStyle
+{
+  enum Type
+  {
+    DEFAULT, ///< The default font's style.
+    INPUT    ///< The input font's style.
+  };
+};
+
 /**
  * @brief Sets the font's style property.
  *
 /**
  * @brief Sets the font's style property.
  *
@@ -87,7 +96,7 @@ const unsigned int FONT_SLANT_STRING_TABLE_COUNT = sizeof( FONT_SLANT_STRING_TAB
  * @param[in] value The value of the font's style.
  *
  */
  * @param[in] value The value of the font's style.
  *
  */
-void SetFontStyleProperty( ControllerPtr controller, const Property::Value& value );
+void SetFontStyleProperty( ControllerPtr controller, const Property::Value& value, FontStyle::Type type );
 
 /**
  * @brief Retrieves the font's style property.
 
 /**
  * @brief Retrieves the font's style property.
@@ -95,8 +104,34 @@ void SetFontStyleProperty( ControllerPtr controller, const Property::Value& valu
  * @param[in] controller The text's controller.
  * @param[out] value The value of the font's style.
  */
  * @param[in] controller The text's controller.
  * @param[out] value The value of the font's style.
  */
-void GetFontStyleProperty( ControllerPtr controller, Property::Value& value );
+void GetFontStyleProperty( ControllerPtr controller, Property::Value& value, FontStyle::Type type );
+
+/**
+ * @brief Converts a weight string into @e FontWeight.
+ *
+ * @param[in] weightStr The weight string. Must end with '\0'.
+ *
+ * @return The @e FontWeight value corresponding to the string.
+ */
+FontWeight StringToWeight( const char* const weightStr );
 
 
+/**
+ * @brief Converts a width string into @e FontWidth.
+ *
+ * @param[in] widthStr The width string. Must end with '\0'.
+ *
+ * @return The @e FontWidth value corresponding to the string.
+ */
+FontWidth StringToWidth( const char* const widthStr );
+
+/**
+ * @brief Converts a slant string into @e FontSlant.
+ *
+ * @param[in] slantStr The slant string. Must end with '\0'.
+ *
+ * @return The @e FontSlant value corresponding to the string.
+ */
+FontSlant StringToSlant( const char* const slantStr );
 } // namespace Text
 
 } // namespace Toolkit
 } // namespace Text
 
 } // namespace Toolkit
index e222f99..f2205f5 100644 (file)
@@ -101,7 +101,10 @@ public:
       DECORATION_BOUNDING_BOX,                  ///< name "decorationBoundingBox",               The decorations (handles etc) will positioned within this area on-screen, type RECTANGLE
       INPUT_METHOD_SETTINGS,                    ///< name "inputMethodSettings",                 The settings to relating to the System's Input Method, Key and Value      type MAP
       INPUT_COLOR,                              ///< name "inputColor",                          The color of the new input text,                                          type VECTOR4
       DECORATION_BOUNDING_BOX,                  ///< name "decorationBoundingBox",               The decorations (handles etc) will positioned within this area on-screen, type RECTANGLE
       INPUT_METHOD_SETTINGS,                    ///< name "inputMethodSettings",                 The settings to relating to the System's Input Method, Key and Value      type MAP
       INPUT_COLOR,                              ///< name "inputColor",                          The color of the new input text,                                          type VECTOR4
-      ENABLE_MARKUP                             ///< name "enableMarkup",                        Whether the mark-up processing is enabled.                                type BOOLEAN
+      ENABLE_MARKUP,                            ///< name "enableMarkup",                        Whether the mark-up processing is enabled.                                type BOOLEAN
+      INPUT_FONT_FAMILY,                        ///< name "inputFontFamily",                     The font's family of the new input text,                                  type STRING
+      INPUT_FONT_STYLE,                         ///< name "inputFontStyle",                      The font's style of the new input text,                                   type STRING
+      INPUT_POINT_SIZE                          ///< name "inputPointSize",                      The font's size of the new input text in points,                          type FLOAT
     };
   };
 
     };
   };
 
index 7c73868..dd40aa1 100644 (file)
@@ -87,4 +87,28 @@ field.SetProperty( TextLabel::Property::TEXT, "<color value='#FF0000'>Red Text</
 field.text = "<color value='#FF0000'>Red Text</color>"; // Color packed with the web color format (6 characters).
 ~~~
 
 field.text = "<color value='#FF0000'>Red Text</color>"; // Color packed with the web color format (6 characters).
 ~~~
 
+## \<font\>
+
+Sets the font values of the characters inside the tag.
+
+Supported attributes are:
+- *family* The name of the font.
+- *size* The size of the font in points.
+- *weight* The weight of the font.
+- *width* The width of the font
+- *slant* The slant of the font.
+
+See the [Font Selection](@ref font-selection) to have a view of the possible values for the *weight*, *width* and *slant* attributes.
+
+~~~{.cpp}
+// C++
+field.SetProperty( TextLabel::Property::TEXT, "<font family='SamsungSans' weight='bold'>Hello world</font>" );
+~~~
+
+~~~{.js}
+// JavaScript
+
+field.text = "<font family='SamsungSans' weight='bold'>Hello world</font>";
+~~~
+
 */
 */
index dbe468f..c06c434 100644 (file)
@@ -11,7 +11,7 @@ The Dali::Toolkit::TextField is a control which provides a single-line editable
 
 Before any text has been entered, the TextField can display some placeholder text.
 An alternative placeholder can be displayed when the TextField has keyboard focus.
 
 Before any text has been entered, the TextField can display some placeholder text.
 An alternative placeholder can be displayed when the TextField has keyboard focus.
-For example a TextField used to enter a username could initially show "Unknown Name", and then show "Enter Name." when the cursor is shown. 
+For example a TextField used to enter a username could initially show "Unknown Name", and then show "Enter Name." when the cursor is shown.
 
 ~~~{.cpp}
 // C++
 
 ~~~{.cpp}
 // C++
@@ -59,13 +59,16 @@ Mark-up tags can be used to change the style of the text. See the [Mark-up Style
 
 ### Input Style
 
 
 ### Input Style
 
-The input style can be changed through the control properties. Current supported input style properties are:
+The input style can be changed through the control properties. All subsequent characters added will be rendered with the new input style.
 
 
-#### INPUT_COLOR
+Note the input style may change if the cursor is updated by tapping in a new position.
 
 
-Sets the input color. All subsequent characters added will be rendered with the input color.
+Current supported input style properties are:
 
 
-Note the input color may change if the cursor is updated by tapping in a new position.
+- *INPUT_COLOR* Sets the input color. The property expects a Vector4 with the red, green, blue and alpha values clamped between 0 and 1.
+- *INPUT_FONT_FAMILY* Sets the input font's family name. The property expects the name of the font. If the new text is not supported by the given font a suitable one will be set.
+- *INPUT_FONT_STYLE* Sets the input font's style. The property expects a json formatted string with the font's style. See the [Font Selection](@ref font-selection) section for more details.
+- *INPUT_POINT_SIZE* Sets the input font's size. The property expects a float with the font's size in points. See the [Font Selection](@ref font-selection) section for more details.
 
 ### Text Alignment
 
 
 ### Text Alignment
 
@@ -167,6 +170,9 @@ field.placeholderTextColor = dali.COLOR_BLACK;
  inputMethodSettings               | INPUT_METHOD_SETTINGS                |  MAP         | O            | X
  inputColor                        | INPUT_COLOR                          |  VECTOR4     | O            | X
  enableMarkup                      | ENABLE_MARKUP                        |  BOOLEAN     | O            | X
  inputMethodSettings               | INPUT_METHOD_SETTINGS                |  MAP         | O            | X
  inputColor                        | INPUT_COLOR                          |  VECTOR4     | O            | X
  enableMarkup                      | ENABLE_MARKUP                        |  BOOLEAN     | O            | X
+ inputFontFamily                   | INPUT_FONT_FAMILY                    |  STRING      | O            | X
+ inputFontStyle                    | INPUT_FONT_STYLE                     |  STRING      | O            | X
+ inputPointSize                    | INPUT_POINT_SIZE                     |  FLOAT       | O            | X
 
 @class TextField
 
 
 @class TextField