Markup processor. 89/52689/15
authorVictor Cebollada <v.cebollada@samsung.com>
Wed, 25 Nov 2015 14:15:23 +0000 (14:15 +0000)
committerVictor Cebollada <v.cebollada@samsung.com>
Wed, 16 Dec 2015 15:24:55 +0000 (15:24 +0000)
Creates a 'skeleton' of the mark-up processor.

Change-Id: Id98953bda8a22cb9ef2a38c2995c7aa757c95307
Signed-off-by: Victor Cebollada <v.cebollada@samsung.com>
dali-toolkit/internal/file.list
dali-toolkit/internal/text/character-set-conversion.cpp
dali-toolkit/internal/text/character-set-conversion.h
dali-toolkit/internal/text/markup-processor-helper-functions.cpp [new file with mode: 0644]
dali-toolkit/internal/text/markup-processor-helper-functions.h [new file with mode: 0644]
dali-toolkit/internal/text/markup-processor.cpp [new file with mode: 0644]
dali-toolkit/internal/text/markup-processor.h [new file with mode: 0644]
dali-toolkit/internal/text/text-controller-impl.h
dali-toolkit/internal/text/text-controller.cpp
dali-toolkit/internal/text/text-controller.h

index ad19367..0cc5763 100644 (file)
@@ -84,6 +84,8 @@ toolkit_src_files = \
    $(toolkit_src_dir)/text/character-set-conversion.cpp \
    $(toolkit_src_dir)/text/clipping/text-clipper.cpp \
    $(toolkit_src_dir)/text/logical-model-impl.cpp \
+   $(toolkit_src_dir)/text/markup-processor.cpp \
+   $(toolkit_src_dir)/text/markup-processor-helper-functions.cpp \
    $(toolkit_src_dir)/text/multi-language-support.cpp \
    $(toolkit_src_dir)/text/segmentation.cpp \
    $(toolkit_src_dir)/text/shaper.cpp \
index 67c294b..ac8b317 100644 (file)
@@ -71,6 +71,11 @@ namespace
   };
 } // namespace
 
+uint8_t GetUtf8Length( uint8_t utf8LeadByte )
+{
+  return UTF8_LENGTH[utf8LeadByte];
+}
+
 uint32_t GetNumberOfUtf8Characters( const uint8_t* const utf8, uint32_t length )
 {
   uint32_t numberOfCharacters = 0u;
index b60a344..730016b 100644 (file)
@@ -32,6 +32,15 @@ namespace Text
 {
 
 /**
+ * @brief Retrieves the number of bytes of a utf8 character.
+ *
+ * @param[in] utf8LeadByte The lead byte of the utf8 character.
+ *
+ * @return The number of bytes of the character.
+ */
+uint8_t GetUtf8Length( uint8_t utf8LeadByte );
+
+/**
  * @brief Retrieves the number of characters of the text array encoded in UTF8
  *
  * @param[in] utf8 The pointer to the UTF8 array.
diff --git a/dali-toolkit/internal/text/markup-processor-helper-functions.cpp b/dali-toolkit/internal/text/markup-processor-helper-functions.cpp
new file mode 100644 (file)
index 0000000..122335e
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * 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/text/markup-processor-helper-functions.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+namespace
+{
+const char WHITE_SPACE       = 0x20; // ASCII value of the white space.
+const char LAST_UPPER_CASE   = 0x5b; // ASCII value of the one after the last upper case character (Z).
+const char TO_LOWER_CASE     = 32;   // Value to add to a upper case character to transform it into a lower case.
+}
+
+bool TokenComparison( const std::string& string1, const char* const stringBuffer2, Length length )
+{
+  const Length stringSize = string1.size();
+  if( stringSize != length )
+  {
+    // Early return. Strings have different sizes.
+    return false;
+  }
+
+  const char* const stringBuffer1 = string1.c_str();
+
+  for( std::size_t index = 0; index < stringSize; ++index )
+  {
+    char character = *( stringBuffer2 + index );
+    if( *( stringBuffer1 + index ) != ( ( ( character < LAST_UPPER_CASE ) && ( '0' != character ) ) ? character + TO_LOWER_CASE : character ) )
+    {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+void SkipWhiteSpace( const char*& markupStringBuffer,
+                     const char* const markupStringEndBuffer )
+{
+  for( ; ( WHITE_SPACE >= *markupStringBuffer ) && ( markupStringBuffer < markupStringEndBuffer ); ++markupStringBuffer );
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/text/markup-processor-helper-functions.h b/dali-toolkit/internal/text/markup-processor-helper-functions.h
new file mode 100644 (file)
index 0000000..cf494d2
--- /dev/null
@@ -0,0 +1,91 @@
+#ifndef __DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_HELPER_FUNCTIONS_H__
+#define __DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_HELPER_FUNCTIONS_H__
+
+/*
+ * 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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/dali-vector.h>
+#include <string>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/text-definitions.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+/**
+ * @brief Stores an attribute pair: name, value.
+ */
+struct Attribute
+{
+  const char* nameBuffer;
+  const char* valueBuffer;
+  Length nameLength;
+  Length valueLength;
+};
+
+/**
+ * @brief Stores a tag and its attributes.
+ */
+ struct Tag
+ {
+   Vector<Attribute> attributes;
+   const char* buffer;
+   Length length;
+   bool isEndTag;
+ };
+
+/**
+ * @brief Compare if two tokens are equal.
+ *
+ * @pre @p string1 must be lower case. (The html-ish constant tokens)
+ * The @p stringBuffer2 parameter is transformed to lower case.
+ * This function is used in the mark-up parser.
+ * It has no sense to transform the constants html-ish tokens to lower case when
+ * it's known they already are.
+ *
+ * @param[in] string1 The html-ish constant token.
+ * @param[in] stringBuffer2 Pointer to the html-ish token buffer.
+ * @param[in] length The length of the html-ish token.
+ *
+ * @return @e true if both strings are equal.
+ */
+bool TokenComparison( const std::string& string1, const char* const stringBuffer2, Length length );
+
+/**
+ * @brief Skips any unnecessary white space.
+ *
+ * @param[in,out] markupStringBuffer The mark-up string buffer. It's a const iterator pointing the current character.
+ * @param[in] markupStringEndBuffer Pointer to one character after the end of the mark-up string buffer.
+ */
+void SkipWhiteSpace( const char*& markupStringBuffer,
+                     const char* const markupStringEndBuffer );
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_HELPER_FUNCTIONS_H__
diff --git a/dali-toolkit/internal/text/markup-processor.cpp b/dali-toolkit/internal/text/markup-processor.cpp
new file mode 100644 (file)
index 0000000..84707ad
--- /dev/null
@@ -0,0 +1,446 @@
+/*
+ * 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/text/markup-processor.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/character-set-conversion.h>
+#include <dali-toolkit/internal/text/markup-processor-helper-functions.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+namespace
+{
+// HTML-ISH tag and attribute constants.
+// Note they must be lower case in order to make the comparison to work
+// as the parser converts all the read tags to lower case.
+const std::string XHTML_COLOR_TAG("color");
+const std::string XHTML_FONT_TAG("font");
+const std::string XHTML_B_TAG("b");
+const std::string XHTML_I_TAG("i");
+const std::string XHTML_U_TAG("u");
+const std::string XHTML_SHADOW_TAG("shadow");
+const std::string XHTML_GLOW_TAG("glow");
+const std::string XHTML_OUTLINE_TAG("outline");
+
+const char LESS_THAN         = '<';
+const char GREATER_THAN      = '>';
+const char EQUAL             = '=';
+const char QUOTATION_MARK    = '\'';
+const char LINE_SEPARATOR_CR = 0x0D; // Carriage return character  CR
+const char LINE_SEPARATOR_LF = 0x0A; // New line character         LF
+const char SLASH             = '/';
+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.
+
+/**
+ * @brief Splits the tag string into the tag name and its attributes.
+ *
+ * The attributes are stored in a vector in the tag.
+ *
+ * @param[in,out] tag The tag.
+ */
+void ParseAttributes( Tag& tag )
+{
+  tag.attributes.Resize( MAX_NUM_OF_ATTRIBUTES );
+
+  // Find first the tag name.
+  bool isQuotationOpen = false;
+
+  const char* tagBuffer = tag.buffer;
+  const char* const tagEndBuffer = tagBuffer + tag.length;
+  tag.length = 0u;
+  for( ; tagBuffer < tagEndBuffer; ++tagBuffer )
+  {
+    const char character = *tagBuffer;
+    if( WHITE_SPACE < character )
+    {
+      ++tag.length;
+    }
+    else
+    {
+      // Stops counting the length of the tag when a white space is found.
+      // @note a white space is the WHITE_SPACE character and anything below as 'tab', 'return' or 'control characters'.
+      break;
+    }
+  }
+  SkipWhiteSpace( tagBuffer, tagEndBuffer );
+
+  // Find the attributes.
+  unsigned int attributeIndex = 0u;
+  const char* nameBuffer = NULL;
+  const char* valueBuffer = NULL;
+  Length nameLength = 0u;
+  Length valueLength = 0u;
+
+  bool addToNameValue = true;
+  Length numberOfWhiteSpace = 0u;
+  for( ; tagBuffer < tagEndBuffer; ++tagBuffer )
+  {
+    const char character = *tagBuffer;
+    if( ( WHITE_SPACE >= character ) && !isQuotationOpen )
+    {
+      if( NULL != valueBuffer )
+      {
+        // Remove white spaces at the end of the value.
+        valueLength -= numberOfWhiteSpace;
+      }
+
+      if( ( NULL != nameBuffer ) && ( NULL != valueBuffer ) )
+      {
+        // Every time a white space is found, a new attribute is created and stored in the attributes vector.
+        Attribute& attribute = *( tag.attributes.Begin() + attributeIndex );
+        ++attributeIndex;
+
+        attribute.nameBuffer = nameBuffer;
+        attribute.valueBuffer = valueBuffer;
+        attribute.nameLength = nameLength;
+        attribute.valueLength = valueLength;
+
+        nameBuffer = NULL;
+        valueBuffer = NULL;
+        nameLength = 0u;
+        valueLength = 0u;
+
+        addToNameValue = true; // next read characters will be added to the name.
+      }
+    }
+    else if( EQUAL == character ) // '='
+    {
+      addToNameValue = false; // next read characters will be added to the value.
+      SkipWhiteSpace( tagBuffer, tagEndBuffer );
+    }
+    else if( QUOTATION_MARK == character ) // '\''
+    {
+      // Do not add quotation marks to neither name nor value.
+      isQuotationOpen = !isQuotationOpen;
+
+      if( isQuotationOpen )
+      {
+        ++tagBuffer;
+        SkipWhiteSpace( tagBuffer, tagEndBuffer );
+        --tagBuffer;
+      }
+    }
+    else
+    {
+      // Adds characters to the name or the value.
+      if( addToNameValue )
+      {
+        if( NULL == nameBuffer )
+        {
+          nameBuffer = tagBuffer;
+        }
+        ++nameLength;
+      }
+      else
+      {
+        if( isQuotationOpen )
+        {
+          if( WHITE_SPACE >= character )
+          {
+            ++numberOfWhiteSpace;
+          }
+          else
+          {
+            numberOfWhiteSpace = 0u;
+          }
+        }
+        if( NULL == valueBuffer )
+        {
+          valueBuffer = tagBuffer;
+        }
+        ++valueLength;
+      }
+    }
+  }
+
+  if( NULL != valueBuffer )
+  {
+    // Remove white spaces at the end of the value.
+    valueLength -= numberOfWhiteSpace;
+  }
+
+  if( ( NULL != nameBuffer ) && ( NULL != valueBuffer ) )
+  {
+    // Checks if the last attribute needs to be added.
+    Attribute& attribute = *( tag.attributes.Begin() + attributeIndex );
+    ++attributeIndex;
+
+    attribute.nameBuffer = nameBuffer;
+    attribute.valueBuffer = valueBuffer;
+    attribute.nameLength = nameLength;
+    attribute.valueLength = valueLength;
+  }
+
+  // Resize the vector of attributes.
+  tag.attributes.Resize( attributeIndex );
+}
+
+/**
+ * @brief It parses a tag and its attributes if the given iterator @e it is pointing at a tag beginning.
+ *
+ * @param[in,out] markupStringBuffer The mark-up string buffer. It's a const iterator pointing the current character.
+ * @param[in] markupStringEndBuffer Pointer to one character after the end of the mark-up string buffer.
+ * @param[out] tag The tag with its attributes.
+ *
+ * @return @e true if the iterator @e it is pointing a mark-up tag. Otherwise @e false.
+ */
+bool IsTag( const char*& markupStringBuffer,
+            const char* const markupStringEndBuffer,
+            Tag& tag )
+{
+  bool isTag = false;
+  bool isQuotationOpen = false;
+  bool attributesFound = false;
+  tag.isEndTag = false;
+
+  const char character = *markupStringBuffer;
+  if( LESS_THAN == character ) // '<'
+  {
+    tag.buffer = NULL;
+    tag.length = 0u;
+
+    // if the iterator is pointing to a '<' character, then check if it's a mark-up tag is needed.
+    ++markupStringBuffer;
+    if( markupStringBuffer < markupStringEndBuffer )
+    {
+      SkipWhiteSpace( markupStringBuffer, markupStringEndBuffer );
+
+      for( ; ( !isTag ) && ( markupStringBuffer < markupStringEndBuffer ); ++markupStringBuffer )
+      {
+        const char character = *markupStringBuffer;
+
+        if( SLASH == character ) // '/'
+        {
+          // if the tag has a '/' then it's an end or empty tag.
+          tag.isEndTag = true;
+
+          if( ( markupStringBuffer + 1u < markupStringEndBuffer ) && ( WHITE_SPACE >= *( markupStringBuffer + 1u ) ) && ( !isQuotationOpen ) )
+          {
+            ++markupStringBuffer;
+            SkipWhiteSpace( markupStringBuffer, markupStringEndBuffer );
+            --markupStringBuffer;
+          }
+        }
+        else if( GREATER_THAN == character ) // '>'
+        {
+          isTag = true;
+        }
+        else if( QUOTATION_MARK == character )
+        {
+          isQuotationOpen = !isQuotationOpen;
+          ++tag.length;
+        }
+        else if( WHITE_SPACE >= character ) // ' '
+        {
+          // If the tag contains white spaces then it may have attributes.
+          if( !isQuotationOpen )
+          {
+            attributesFound = true;
+          }
+          ++tag.length;
+        }
+        else
+        {
+          if( NULL == tag.buffer )
+          {
+            tag.buffer = markupStringBuffer;
+          }
+
+          // If it's not any of the 'special' characters then just add it to the tag string.
+          ++tag.length;
+        }
+      }
+    }
+
+    // If the tag string has white spaces, then parse the attributes is needed.
+    if( attributesFound )
+    {
+      ParseAttributes( tag );
+    }
+  }
+
+  return isTag;
+}
+
+} // namespace
+
+void ProcessMarkupString( const std::string& markupString, MarkupProcessData& markupProcessData )
+{
+  // Reserve space for the plain text.
+  const Length markupStringSize = markupString.size();
+  markupProcessData.markupProcessedText.reserve( markupStringSize );
+
+  // Get the mark-up string buffer.
+  const char* markupStringBuffer = markupString.c_str();
+  const char* const markupStringEndBuffer = markupStringBuffer + markupStringSize;
+
+  Tag tag;
+  CharacterIndex characterIndex = 0u;
+  for( ; markupStringBuffer < markupStringEndBuffer; )
+  {
+    if( IsTag( markupStringBuffer,
+               markupStringEndBuffer,
+               tag ) )
+    {
+      if( TokenComparison( XHTML_COLOR_TAG, tag.buffer, tag.length ) )
+      {
+        if( !tag.isEndTag )
+        {
+          // Create a new color run.
+        }
+        else
+        {
+          // Pop the top of the stack and set the number of characters of the run.
+        }
+      } // <color></color>
+      else if( TokenComparison( XHTML_I_TAG, tag.buffer, tag.length ) )
+      {
+        if( !tag.isEndTag )
+        {
+          // Create a new font run.
+        }
+        else
+        {
+          // Pop the top of the stack and set the number of characters of the run.
+        }
+      } // <i></i>
+      else if( TokenComparison( XHTML_U_TAG, tag.buffer, tag.length ) )
+      {
+        if( !tag.isEndTag )
+        {
+          // Create a new underline run.
+        }
+        else
+        {
+          // Pop the top of the stack and set the number of characters of the run.
+        }
+      } // <u></u>
+      else if( TokenComparison( XHTML_B_TAG, tag.buffer, tag.length ) )
+      {
+        if( !tag.isEndTag )
+        {
+          // Create a new font run.
+        }
+        else
+        {
+          // Pop the top of the stack and set the number of characters of the run.
+        }
+      } // <b></b>
+      else if( TokenComparison( XHTML_FONT_TAG, tag.buffer, tag.length ) )
+      {
+        if( !tag.isEndTag )
+        {
+          // Create a new font run.
+        }
+        else
+        {
+          // Pop the top of the stack and set the number of characters of the run.
+        }
+      } // <font></font>
+      else if( TokenComparison( XHTML_SHADOW_TAG, tag.buffer, tag.length ) )
+      {
+        if( !tag.isEndTag )
+        {
+          // Create a new shadow run.
+        }
+        else
+        {
+          // Pop the top of the stack and set the number of characters of the run.
+        }
+      } // <shadow></shadow>
+      else if( TokenComparison( XHTML_GLOW_TAG, tag.buffer, tag.length ) )
+      {
+        if( !tag.isEndTag )
+        {
+          // Create a new glow run.
+        }
+        else
+        {
+          // Pop the top of the stack and set the number of characters of the run.
+        }
+      } // <glow></glow>
+      else if( TokenComparison( XHTML_OUTLINE_TAG, tag.buffer, tag.length ) )
+      {
+        if( !tag.isEndTag )
+        {
+          // Create a new outline run.
+        }
+        else
+        {
+          // Pop the top of the stack and set the number of characters of the run.
+        }
+      } // <outline></outline>
+    }  // end if( IsTag() )
+    else
+    {
+      unsigned char character = *markupStringBuffer;
+
+      if( ( BACK_SLASH == character ) && ( markupStringBuffer + 1u < markupStringEndBuffer ) )
+      {
+        // Adding < or > special character.
+        const unsigned char nextCharacter = *( markupStringBuffer + 1u );
+        if( ( LESS_THAN == nextCharacter ) || ( GREATER_THAN == nextCharacter ) )
+        {
+          character = nextCharacter;
+          ++markupStringBuffer;
+        }
+      }
+      else if( ( LINE_SEPARATOR_CR == character ) && ( markupStringBuffer + 1u < markupStringEndBuffer ) )
+      {
+        // Replacing CR+LF end line by LF.
+        if( LINE_SEPARATOR_LF == *( markupStringBuffer + 1u ) )
+        {
+          character = LINE_SEPARATOR_LF;
+          ++markupStringBuffer;
+        }
+      }
+
+      const unsigned char numberOfBytes = GetUtf8Length( character );
+
+      markupProcessData.markupProcessedText.push_back( character );
+      for( unsigned char i = 1u; i < numberOfBytes; ++i )
+      {
+        ++markupStringBuffer;
+        markupProcessData.markupProcessedText.push_back( *markupStringBuffer );
+      }
+
+      ++characterIndex;
+      ++markupStringBuffer;
+    }
+  }
+
+  // Resize the model's vectors.
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/text/markup-processor.h b/dali-toolkit/internal/text/markup-processor.h
new file mode 100644 (file)
index 0000000..86ec1a6
--- /dev/null
@@ -0,0 +1,59 @@
+#ifndef __DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_H__
+#define __DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_H__
+
+/*
+ * 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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <string>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+/**
+ * @brief Keeps the plain text and references to vectors from the model which stores runs with text styles.
+ */
+struct MarkupProcessData
+{
+  MarkupProcessData()
+  : markupProcessedText()
+  {}
+
+  std::string markupProcessedText;
+};
+
+/**
+ * @brief Process the mark-up string.
+ *
+ * @param[in] markupString The mark-up string.
+ * @param[out] markupProcessData The plain text and the style.
+ */
+void ProcessMarkupString( const std::string& markupString, MarkupProcessData& markupProcessData );
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_H__
index 927352c..190549c 100644 (file)
@@ -182,8 +182,8 @@ struct FontDefaults
   FontDefaults()
   : mFontDescription(),
     mFontStyle(),
-    mDefaultPointSize(0.0f),
-    mFontId(0u)
+    mDefaultPointSize( 0.f ),
+    mFontId( 0u )
   {
     // Initially use the default platform font
     TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
@@ -226,7 +226,8 @@ struct Controller::Impl
     mOperationsPending( NO_OPERATION ),
     mMaximumNumberOfCharacters( 50u ),
     mRecalculateNaturalSize( true ),
-    mUserDefinedFontFamily( false )
+    mUserDefinedFontFamily( false ),
+    mMarkupProcessorEnabled( false )
   {
     mLogicalModel = LogicalModel::New();
     mVisualModel  = VisualModel::New();
@@ -512,7 +513,7 @@ struct Controller::Impl
 
   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.
 };
 
 } // namespace Text
index 2a06637..27f5cbf 100644 (file)
@@ -28,6 +28,7 @@
 #include <dali-toolkit/internal/text/bidirectional-support.h>
 #include <dali-toolkit/internal/text/character-set-conversion.h>
 #include <dali-toolkit/internal/text/layouts/layout-parameters.h>
+#include <dali-toolkit/internal/text/markup-processor.h>
 #include <dali-toolkit/internal/text/text-controller-impl.h>
 
 namespace
@@ -73,6 +74,16 @@ void Controller::EnableTextInput( DecoratorPtr decorator )
   }
 }
 
+void Controller::SetMarkupProcessorEnabled( bool enable )
+{
+  mImpl->mMarkupProcessorEnabled = enable;
+}
+
+bool Controller::IsMarkupProcessorEnabled() const
+{
+  return mImpl->mMarkupProcessorEnabled;
+}
+
 void Controller::SetText( const std::string& text )
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::SetText\n" );
@@ -99,20 +110,37 @@ void Controller::SetText( const std::string& text )
 
   if( !text.empty() )
   {
+    MarkupProcessData markupProcessData;
+
+    Length textSize = 0u;
+    const uint8_t* utf8 = NULL;
+    if( mImpl->mMarkupProcessorEnabled )
+    {
+      ProcessMarkupString( text, markupProcessData );
+      textSize = markupProcessData.markupProcessedText.size();
+
+      // This is a bit horrible but std::string returns a (signed) char*
+      utf8 = reinterpret_cast<const uint8_t*>( markupProcessData.markupProcessedText.c_str() );
+    }
+    else
+    {
+      textSize = text.size();
+
+      // This is a bit horrible but std::string returns a (signed) char*
+      utf8 = reinterpret_cast<const uint8_t*>( text.c_str() );
+    }
+
     //  Convert text into UTF-32
     Vector<Character>& utf32Characters = mImpl->mLogicalModel->mText;
-    utf32Characters.Resize( text.size() );
-
-    // This is a bit horrible but std::string returns a (signed) char*
-    const uint8_t* utf8 = reinterpret_cast<const uint8_t*>( text.c_str() );
+    utf32Characters.Resize( textSize );
 
     // Transform a text array encoded in utf8 into an array encoded in utf32.
     // It returns the actual number of characters.
-    Length characterCount = Utf8ToUtf32( utf8, text.size(), utf32Characters.Begin() );
+    Length characterCount = Utf8ToUtf32( utf8, textSize, utf32Characters.Begin() );
     utf32Characters.Resize( characterCount );
 
-    DALI_ASSERT_DEBUG( text.size() >= characterCount && "Invalid UTF32 conversion length" );
-    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::SetText %p UTF8 size %d, UTF32 size %d\n", this, text.size(), mImpl->mLogicalModel->mText.Count() );
+    DALI_ASSERT_DEBUG( textSize >= characterCount && "Invalid UTF32 conversion length" );
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::SetText %p UTF8 size %d, UTF32 size %d\n", this, textSize, mImpl->mLogicalModel->mText.Count() );
 
     // To reset the cursor position
     lastCursorIndex = characterCount;
index 5a80e35..0955431 100644 (file)
@@ -114,6 +114,24 @@ public:
   void EnableTextInput( DecoratorPtr decorator );
 
   /**
+   * @brief Enables/disables the mark-up processor.
+   *
+   * By default is disabled.
+   *
+   * @param[in] enable Whether to enable the mark-up processor.
+   */
+  void SetMarkupProcessorEnabled( bool enable );
+
+  /**
+   * @brief Retrieves whether the mark-up processor is enabled.
+   *
+   * By default is disabled.
+   *
+   * @return @e true if the mark-up processor is enabled, otherwise returns @e false.
+   */
+  bool IsMarkupProcessorEnabled() const;
+
+  /**
    * @brief Replaces any text previously set.
    *
    * @note This will be converted into UTF-32 when stored in the text model.