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 );
-// 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 );
 
+  // To be completed ...
+  Vector<FontDescriptionRun> fontDescriptions;
+  FontId defaultFontId = 0u;
   Vector<FontRun> fonts;
+
   // 3) Validate the fonts
   multilanguageSupport.ValidateFonts( utf32,
                                       scripts,
+                                      fontDescriptions,
+                                      defaultFontId,
                                       fonts );
-
   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_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;
 
@@ -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_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;
 }
 
@@ -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 );
 
-  // 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 );
 
@@ -402,6 +408,14 @@ int UtcDaliTextFieldSetPropertyP(void)
   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;
 }
 
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>
-#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/text-font-style.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, "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 )
@@ -214,7 +217,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       }
       case Toolkit::TextField::Property::FONT_STYLE:
       {
-        SetFontStyleProperty( impl.mController, value );
+        SetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT );
         break;
       }
       case Toolkit::TextField::Property::POINT_SIZE:
@@ -578,6 +581,31 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
         }
         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
 }
@@ -640,7 +668,7 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
       }
       case Toolkit::TextField::Property::FONT_STYLE:
       {
-        GetFontStyleProperty( impl.mController, value );
+        GetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT );
         break;
       }
       case Toolkit::TextField::Property::POINT_SIZE:
@@ -708,14 +736,6 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
         }
         break;
       }
-      case Toolkit::TextField::Property::INPUT_COLOR:
-      {
-        if( impl.mController )
-        {
-          value = impl.mController->GetInputColor();
-        }
-        break;
-      }
       case Toolkit::TextField::Property::SHADOW_OFFSET:
       {
         if ( impl.mController )
@@ -869,6 +889,14 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
       {
         break;
       }
+      case Toolkit::TextField::Property::INPUT_COLOR:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->GetInputColor();
+        }
+        break;
+      }
       case Toolkit::TextField::Property::ENABLE_MARKUP:
       {
         if( impl.mController )
@@ -877,6 +905,27 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
         }
         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
   }
 
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>
-#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/text-font-style.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:
       {
-        SetFontStyleProperty( impl.mController, value );
+        SetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT );
         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:
       {
-        GetFontStyleProperty( impl.mController, value );
+        GetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT );
         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/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 \
@@ -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/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 \
@@ -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-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 \
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.
-  bool         isDefault;    ///< Whether the font is a default font not defined by the user.
 };
 
 } // namespace Text
index cd562ec..a9e6eab 100644 (file)
@@ -21,6 +21,9 @@
 // EXTERNAL INCLUDES
 #include <dali/public-api/math/vector4.h>
 
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/text-definitions.h>
+
 namespace Dali
 {
 
@@ -35,7 +38,37 @@ namespace Text
  */
 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
index bdbbbfe..d4a9d94 100644 (file)
@@ -31,6 +31,19 @@ namespace Toolkit
 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() );
@@ -256,16 +269,28 @@ void LogicalModel::UpdateTextStyleRuns( CharacterIndex index, int numberOfCharac
                                  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;
-  unsigned int lastRunIndex = 0u;
-  bool overriden = false;
 
   // 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 )
@@ -275,20 +300,131 @@ void LogicalModel::RetrieveStyle( CharacterIndex index, InputStyle& style )
     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.
-  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()
 {
+  ClearFontDescriptionRuns();
 }
 
 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/font-description-run.h>
 #include <dali-toolkit/internal/text/script-run.h>
 
 namespace Dali
@@ -124,6 +125,11 @@ public:
    */
   void RetrieveStyle( CharacterIndex index, InputStyle& style );
 
+  /**
+   * @brief Clears the font description runs.
+   */
+  void ClearFontDescriptionRuns();
+
 protected:
 
   /**
@@ -150,6 +156,7 @@ public:
   Vector<ScriptRun>                     mScriptRuns;
   Vector<FontRun>                       mFontRuns;
   Vector<ColorRun>                      mColorRuns;
+  Vector<FontDescriptionRun>            mFontDescriptionRuns;
   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 ) );
 }
 
+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;
index 5934467..62be6c8 100644 (file)
@@ -94,6 +94,15 @@ void SkipWhiteSpace( const char*& markupStringBuffer,
 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.
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>
+#include <dali-toolkit/internal/text/markup-processor-font.h>
 #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 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;
+  StyleStack::RunIndex fontRunIndex = 0u;
 
   // 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();
@@ -398,10 +400,34 @@ void ProcessMarkupString( const std::string& markupString, MarkupProcessData& ma
         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.
+          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 ) )
@@ -420,10 +446,35 @@ void ProcessMarkupString( const std::string& markupString, MarkupProcessData& ma
         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.
+          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 ) )
@@ -431,10 +482,35 @@ void ProcessMarkupString( const std::string& markupString, MarkupProcessData& ma
         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.
+          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 ) )
@@ -510,6 +586,15 @@ void ProcessMarkupString( const std::string& markupString, MarkupProcessData& ma
   }
 
   // Resize the model's vectors.
+  if( 0u == fontRunIndex )
+  {
+    markupProcessData.fontRuns.Clear();
+  }
+  else
+  {
+    markupProcessData.fontRuns.Resize( fontRunIndex );
+  }
+
   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>
+#include <dali-toolkit/internal/text/font-description-run.h>
 
 namespace Dali
 {
@@ -39,14 +40,17 @@ namespace Text
  */
 struct MarkupProcessData
 {
-  MarkupProcessData( Vector<ColorRun>& colorRuns )
+MarkupProcessData( Vector<ColorRun>& colorRuns,
+                   Vector<FontDescriptionRun>& fontRuns )
   : colorRuns( colorRuns ),
+    fontRuns( fontRuns ),
     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,
+                                          const Vector<FontDescriptionRun>& fontDescriptions,
+                                          FontId defaultFontId,
                                           Vector<FontRun>& fonts )
 {
+  // Clear any previously validated font.
+  fonts.Clear();
+
   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;
   }
 
-  // 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.
@@ -373,33 +411,46 @@ void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
   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;
-  currentFontRun.isDefault = false;
 
   // 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.
-    const Character character = *( text.Begin() + index );
+    const Character character = *( textBuffer + index );
 
     // 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,
@@ -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.
-    const bool isDefault = ( 0u == 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 )
@@ -527,7 +563,7 @@ void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
         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 )
@@ -536,7 +572,7 @@ void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
         }
         if( 0u == fontId )
         {
-          fontId = fontClient.FindDefaultFont( UTF32_A, pointSize );
+          fontId = fontClient.FindDefaultFont( UTF32_A, defaultPointSize );
         }
 
         // Cache the font.
@@ -559,8 +595,7 @@ void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
 
     // 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.
 
@@ -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.isDefault = isDefault;
     }
 
     // Add one more character to the run.
index 4dfc85c..e6105ac 100644 (file)
@@ -97,10 +97,12 @@ public:
                    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,
+                      const Vector<FontDescriptionRun>& fontDescriptions,
+                      FontId defaultFontId,
                       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,
+                                          const Vector<FontDescriptionRun>& fontDescriptions,
+                                          FontId defaultFontId,
                                           Vector<FontRun>& fonts )
 {
   GetImplementation( *this ).ValidateFonts( text,
                                             scripts,
+                                            fontDescriptions,
+                                            defaultFontId,
                                             fonts );
 }
 
index 7e47fd2..bcbb130 100644 (file)
@@ -24,6 +24,7 @@
 
 // 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
@@ -97,8 +98,6 @@ public:
   /**
    * @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.
    *
@@ -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,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,
+                      const Vector<FontDescriptionRun>& fontDescriptions,
+                      FontId defaultFontId,
                       Vector<FontRun>& fonts );
 };
 
index a197d32..f85d410 100644 (file)
@@ -368,17 +368,18 @@ void Controller::Impl::UpdateModel( OperationsMask operationsRequired )
 
     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,
+                                          fontDescriptionRuns,
+                                          defaultFontId,
                                           validFonts );
     }
   }
@@ -517,22 +518,37 @@ bool Controller::Impl::UpdateModelStyle( OperationsMask operationsRequired )
 
 void Controller::Impl::RetrieveDefaultInputStyle( InputStyle& inputStyle )
 {
-  // Set the default text's color.
+  // Sets the default text's color.
   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 )
   {
-    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;
 
-  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;
@@ -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.
 
+    cursorInfo.lineOffset = 0.f;
     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 ) );
 
-  // Set the line height.
+  // Set the line offset and height.
+  cursorInfo.lineOffset = 0.f;
   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,
-                                       cursorPosition.y,
+                                       cursorInfo.lineOffset + offset.y,
                                        cursorInfo.lineHeight );
 
   if( cursorInfo.isSecondaryCursor )
@@ -1976,12 +2000,13 @@ void Controller::Impl::UpdateSelectionHandle( HandleType handleType,
     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,
-                                       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.
index 3ae0c7f..9ee83cc 100644 (file)
@@ -81,6 +81,7 @@ struct CursorInfo
   CursorInfo()
   : primaryPosition(),
     secondaryPosition(),
+    lineOffset( 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.
+  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.
@@ -187,7 +189,12 @@ struct FontDefaults
   : 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();
@@ -205,10 +212,15 @@ struct FontDefaults
     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
@@ -230,7 +242,6 @@ struct Controller::Impl
     mOperationsPending( NO_OPERATION ),
     mMaximumNumberOfCharacters( 50u ),
     mRecalculateNaturalSize( true ),
-    mUserDefinedFontFamily( false ),
     mMarkupProcessorEnabled( false )
   {
     mLogicalModel = LogicalModel::New();
@@ -388,14 +399,6 @@ struct Controller::Impl
   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();
@@ -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.
-  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.
 };
 
index f22278a..3143603 100644 (file)
@@ -20,6 +20,7 @@
 
 // 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>
@@ -61,6 +62,39 @@ namespace Toolkit
 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 ) );
@@ -113,7 +147,8 @@ void Controller::SetText( const std::string& text )
 
   if( !text.empty() )
   {
-    MarkupProcessData markupProcessData( mImpl->mLogicalModel->mColorRuns );
+    MarkupProcessData markupProcessData( mImpl->mLogicalModel->mColorRuns,
+                                         mImpl->mLogicalModel->mFontDescriptionRuns );
 
     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->mUserDefinedFontFamily = true;
+  mImpl->mFontDefaults->familyDefined = true;
 
   // Clear the font-specific data
   ClearFontData();
@@ -310,14 +345,15 @@ const std::string& Controller::GetDefaultFontStyle() const
   return EMPTY_STRING;
 }
 
-void Controller::SetDefaultFontWidth( FontWidth width )
+void Controller::SetDefaultFontWeight( FontWeight weight )
 {
   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();
@@ -328,24 +364,25 @@ void Controller::SetDefaultFontWidth( FontWidth width )
   mImpl->RequestRelayout();
 }
 
-FontWidth Controller::GetDefaultFontWidth() const
+FontWeight Controller::GetDefaultFontWeight() const
 {
   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();
   }
 
-  mImpl->mFontDefaults->mFontDescription.weight = weight;
+  mImpl->mFontDefaults->mFontDescription.width = width;
+  mImpl->mFontDefaults->widthDefined = true;
 
   // Clear the font-specific data
   ClearFontData();
@@ -356,14 +393,14 @@ void Controller::SetDefaultFontWeight( FontWeight weight )
   mImpl->RequestRelayout();
 }
 
-FontWeight Controller::GetDefaultFontWeight() const
+FontWidth Controller::GetDefaultFontWidth() const
 {
   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 )
@@ -374,6 +411,7 @@ void Controller::SetDefaultFontSlant( FontSlant slant )
   }
 
   mImpl->mFontDefaults->mFontDescription.slant = slant;
+  mImpl->mFontDefaults->slantDefined = true;
 
   // Clear the font-specific data
   ClearFontData();
@@ -402,6 +440,7 @@ void Controller::SetDefaultPointSize( float pointSize )
   }
 
   mImpl->mFontDefaults->mDefaultPointSize = pointSize;
+  mImpl->mFontDefaults->sizeDefined = true;
 
   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");
 
-  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();
@@ -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" );
@@ -1564,7 +1817,9 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ
     // 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.
@@ -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 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 )
     {
@@ -1589,6 +1851,55 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ
       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;
 
@@ -2228,6 +2539,7 @@ void Controller::ClearFontData()
 void Controller::ClearStyleData()
 {
   mImpl->mLogicalModel->mColorRuns.Clear();
+  mImpl->mLogicalModel->ClearFontDescriptionRuns();
 }
 
 Controller::Controller( ControlInterface& controlInterface )
index 058719e..a9cc0df 100644 (file)
@@ -224,32 +224,32 @@ public:
   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.
@@ -398,6 +398,90 @@ public:
   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.
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__
 
 /*
- * 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.
@@ -34,20 +34,6 @@ namespace Toolkit
 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 },
@@ -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 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 },
@@ -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] );
 
+namespace FontStyle
+{
+  enum Type
+  {
+    DEFAULT, ///< The default font's style.
+    INPUT    ///< The input font's style.
+  };
+};
+
 /**
  * @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.
  *
  */
-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.
@@ -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.
  */
-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
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
-      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).
 ~~~
 
+## \<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.
-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++
@@ -59,13 +59,16 @@ Mark-up tags can be used to change the style of the text. See the [Mark-up 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
 
@@ -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
+ inputFontFamily                   | INPUT_FONT_FAMILY                    |  STRING      | O            | X
+ inputFontStyle                    | INPUT_FONT_STYLE                     |  STRING      | O            | X
+ inputPointSize                    | INPUT_POINT_SIZE                     |  FLOAT       | O            | X
 
 @class TextField