// 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
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 LESS_THAN = '<';
+const char GREATER_THAN = '>';
+const char EQUAL = '=';
+const char QUOTATION_MARK = '\'';
+const char SLASH = '/';
+const char BACK_SLASH = '\\';
-const char WHITE_SPACE = 0x20; // ASCII value of the white space.
+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.
+
+/**
+ * @brief Struct used to retrieve the style runs from the mark-up string.
+ */
+struct StyleStack
+{
+ typedef VectorBase::SizeType RunIndex;
+
+ Vector<RunIndex> stack; ///< Use a vector as a style stack. Stores the indices pointing where the run is stored inside the logical model.
+ unsigned int topIndex; ///< Points the top of the stack.
+
+ StyleStack()
+ : stack(),
+ topIndex( 0u )
+ {
+ stack.Resize( DEFAULT_VECTOR_SIZE );
+ }
+
+ void Push( RunIndex index )
+ {
+ // Check if there is space inside the style stack.
+ const VectorBase::SizeType size = stack.Count();
+ if( topIndex >= size )
+ {
+ // Resize the style stack.
+ stack.Resize( 2u * size );
+ }
+
+ // Set the run index in the top of the stack.
+ *( stack.Begin() + topIndex ) = index;
+
+ // Reposition the pointer to the top of the stack.
+ ++topIndex;
+ }
+
+ RunIndex Pop()
+ {
+ // Pop the top of the stack.
+ --topIndex;
+ return *( stack.Begin() + topIndex );
+ }
+};
/**
* @brief Splits the tag string into the tag name and its attributes.
const Length markupStringSize = markupString.size();
markupProcessData.markupProcessedText.reserve( markupStringSize );
+ // Stores a struct with the index to the first character of the run, the type of run and its parameters.
+ StyleStack styleStack;
+
+ // 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();
const char* const markupStringEndBuffer = markupStringBuffer + markupStringSize;
if( !tag.isEndTag )
{
// Create a new color run.
+ ColorRun colorRun;
+ colorRun.characterRun.numberOfCharacters = 0u;
+
+ // Set the start character index.
+ colorRun.characterRun.characterIndex = characterIndex;
+
+ // Fill the run with the attributes.
+ ProcessColorTag( tag, colorRun );
+
+ // Push the color run in the logical model.
+ markupProcessData.colorRuns.PushBack( colorRun );
+
+ // Push the index of the run into the stack.
+ styleStack.Push( colorRunIndex );
+
+ // Point the next color run.
+ ++colorRunIndex;
}
else
{
// Pop the top of the stack and set the number of characters of the run.
+ ColorRun& colorRun = *( markupProcessData.colorRuns.Begin() + styleStack.Pop() );
+ colorRun.characterRun.numberOfCharacters = characterIndex - colorRun.characterRun.characterIndex;
}
} // <color></color>
else if( TokenComparison( XHTML_I_TAG, tag.buffer, tag.length ) )
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 ) )
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 ) )
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 ) )
++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 );
}
// Resize the model's vectors.
+ if( 0u == fontRunIndex )
+ {
+ markupProcessData.fontRuns.Clear();
+ }
+ else
+ {
+ markupProcessData.fontRuns.Resize( fontRunIndex );
+ }
+
+ if( 0u == colorRunIndex )
+ {
+ markupProcessData.colorRuns.Clear();
+ }
+ else
+ {
+ markupProcessData.colorRuns.Resize( colorRunIndex );
+ }
}
} // namespace Text