support span tag to be used for grouping font properties & text color.
for example :
Hello <span font-size='50' text-color='blue'>World</span>
using namespace Dali;
using namespace Dali::Toolkit;
class SimpleApp : public ConnectionTracker
{
public:
SimpleApp(Application& application)
: mApplication(application)
{
mApplication.InitSignal().Connect(this, &SimpleApp::Create);
}
void Create(Application& application)
{
Window window = mApplication.GetWindow();
mEditor = TextEditor::New();
mEditor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_CENTER);
mEditor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_CENTER);
mEditor.SetProperty(Actor::Property::POSITION, Vector3(0.f, 0.0f, 0.f));
mEditor.SetProperty(Actor::Property::SIZE, Vector2(300, 300.0f));
window.SetBackgroundColor(Vector4(0.04f, 0.345f, 0.392f, 1.0f));
mEditor.SetProperty(TextEditor::Property::POINT_SIZE, 26.f);
mEditor.SetProperty(TextEditor::Property::ENABLE_MARKUP, true);
mEditor.SetProperty(TextEditor::Property::TEXT, "Hello <span font-size='50' text-color='blue'>World</span>");
window.Add(mEditor);
}
private:
Application& mApplication;
TextEditor mEditor;
};
int DALI_EXPORT_API main(int argc, char** argv)
{
Application application = Application::New(&argc, &argv);
SimpleApp test(application);
application.MainLoop();
return 0;
}
Change-Id: Ie1be3e9d980dbca8ee4f0154000f94defd517a7c
DALI_TEST_EQUALS( backgroundColorIndicesBuffer[7], 2u, TEST_LOCATION);
END_TEST;
+}
+
+int UtcDaliTextEditorTextWithSpan(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliTextEditorTextWithSpan\n");
+
+ TextEditor editor = TextEditor::New();
+ DALI_TEST_CHECK( editor );
+
+ editor.SetProperty( TextEditor ::Property::ENABLE_MARKUP, true );
+ editor.SetProperty( TextEditor::Property::TEXT, "Hello Span" );
+ application.GetScene().Add( editor );
+
+ application.SendNotification();
+ application.Render();
+
+ Vector3 originalSize = editor.GetNaturalSize();
+ editor.SetProperty( TextEditor::Property::TEXT, "H<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red'>ello</span> Span" );
+
+ application.SendNotification();
+ application.Render();
+
+ Vector3 spanSize = editor.GetNaturalSize();
+
+ DALI_TEST_GREATER(spanSize.width, originalSize.width, TEST_LOCATION);
+
+ Toolkit::Internal::TextEditor& editorImpl = GetImpl( editor );
+ const ColorIndex* const colorIndicesBuffer1 = editorImpl.getController()->GetTextModel()->GetColorIndices();
+
+ DALI_TEST_CHECK( colorIndicesBuffer1 );
+
+ //default color
+ DALI_TEST_EQUALS( colorIndicesBuffer1[0], 0u, TEST_LOCATION);
+
+ //span color
+ DALI_TEST_EQUALS( colorIndicesBuffer1[1], 1u, TEST_LOCATION);
+
+ //default color
+ DALI_TEST_EQUALS( colorIndicesBuffer1[6], 0u, TEST_LOCATION);
+
+
+ editor.SetProperty( TextEditor::Property::TEXT, "<span font-size='45'>H</span>ello <span text-color='red'>S</span>pan" );
+
+ application.SendNotification();
+ application.Render();
+
+ const ColorIndex* const colorIndicesBuffer2 = editorImpl.getController()->GetTextModel()->GetColorIndices();
+
+ DALI_TEST_CHECK( colorIndicesBuffer2 );
+
+ //default color
+ DALI_TEST_EQUALS( colorIndicesBuffer2[0], 0u, TEST_LOCATION);
+
+ //default color
+ DALI_TEST_EQUALS( colorIndicesBuffer2[1], 0u, TEST_LOCATION);
+
+ //span color
+ DALI_TEST_EQUALS( colorIndicesBuffer2[6], 1u, TEST_LOCATION);
+
+ //default color
+ DALI_TEST_EQUALS( colorIndicesBuffer2[7], 0u, TEST_LOCATION);
+
+ END_TEST;
}
\ No newline at end of file
DALI_TEST_EQUALS( backgroundColorIndicesBuffer[7], 2u, TEST_LOCATION);
END_TEST;
+}
+
+int UtcDaliTextFieldTextWithSpan(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliTextFieldTextWithSpan\n");
+
+ TextField field = TextField::New();
+ DALI_TEST_CHECK( field );
+
+ field.SetProperty( TextField ::Property::ENABLE_MARKUP, true );
+ field.SetProperty( TextField::Property::TEXT, "Hello Span" );
+ application.GetScene().Add( field );
+
+ application.SendNotification();
+ application.Render();
+
+ Vector3 originalSize = field.GetNaturalSize();
+ field.SetProperty( TextField::Property::TEXT, "H<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red'>ello</span> Span" );
+
+ application.SendNotification();
+ application.Render();
+
+ Vector3 spanSize = field.GetNaturalSize();
+
+ DALI_TEST_GREATER(spanSize.width, originalSize.width, TEST_LOCATION);
+
+ Toolkit::Internal::TextField& fieldImpl = GetImpl( field );
+ const ColorIndex* const colorIndicesBuffer1 = fieldImpl.getController()->GetTextModel()->GetColorIndices();
+
+ DALI_TEST_CHECK( colorIndicesBuffer1 );
+
+ //default color
+ DALI_TEST_EQUALS( colorIndicesBuffer1[0], 0u, TEST_LOCATION);
+
+ //span color
+ DALI_TEST_EQUALS( colorIndicesBuffer1[1], 1u, TEST_LOCATION);
+
+ //default color
+ DALI_TEST_EQUALS( colorIndicesBuffer1[6], 0u, TEST_LOCATION);
+
+
+ field.SetProperty( TextField::Property::TEXT, "<span font-size='45'>H</span>ello <span text-color='red'>S</span>pan" );
+
+ application.SendNotification();
+ application.Render();
+
+ const ColorIndex* const colorIndicesBuffer2 = fieldImpl.getController()->GetTextModel()->GetColorIndices();
+
+ DALI_TEST_CHECK( colorIndicesBuffer2 );
+
+ //default color
+ DALI_TEST_EQUALS( colorIndicesBuffer2[0], 0u, TEST_LOCATION);
+
+ //default color
+ DALI_TEST_EQUALS( colorIndicesBuffer2[1], 0u, TEST_LOCATION);
+
+ //span color
+ DALI_TEST_EQUALS( colorIndicesBuffer2[6], 1u, TEST_LOCATION);
+
+ //default color
+ DALI_TEST_EQUALS( colorIndicesBuffer2[7], 0u, TEST_LOCATION);
+
+ END_TEST;
}
\ No newline at end of file
DALI_TEST_EQUALS( backgroundColorIndicesBuffer[7], 2u, TEST_LOCATION);
END_TEST;
+}
+
+int UtcDaliTextLabelTextWithSpan(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliTextLabelTextWithSpan\n");
+
+ TextLabel label = TextLabel::New();
+ DALI_TEST_CHECK( label );
+
+ label.SetProperty( TextLabel ::Property::ENABLE_MARKUP, true );
+ label.SetProperty( TextLabel::Property::TEXT, "Hello Span" );
+ application.GetScene().Add( label );
+
+ application.SendNotification();
+ application.Render();
+
+ Vector3 originalSize = label.GetNaturalSize();
+ label.SetProperty( TextLabel::Property::TEXT, "H<span font-size='45' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red'>ello</span> Span" );
+
+ application.SendNotification();
+ application.Render();
+
+ Vector3 spanSize = label.GetNaturalSize();
+
+ DALI_TEST_GREATER(spanSize.width, originalSize.width, TEST_LOCATION);
+
+ Toolkit::Internal::TextLabel& labelImpl = GetImpl( label );
+ const ColorIndex* const colorIndicesBuffer1 = labelImpl.getController()->GetTextModel()->GetColorIndices();
+
+ DALI_TEST_CHECK( colorIndicesBuffer1 );
+
+ //default color
+ DALI_TEST_EQUALS( colorIndicesBuffer1[0], 0u, TEST_LOCATION);
+
+ //span color
+ DALI_TEST_EQUALS( colorIndicesBuffer1[1], 1u, TEST_LOCATION);
+
+ //default color
+ DALI_TEST_EQUALS( colorIndicesBuffer1[6], 0u, TEST_LOCATION);
+
+
+ label.SetProperty( TextLabel::Property::TEXT, "<span font-size='45'>H</span>ello <span text-color='red'>S</span>pan" );
+
+ application.SendNotification();
+ application.Render();
+
+ const ColorIndex* const colorIndicesBuffer2 = labelImpl.getController()->GetTextModel()->GetColorIndices();
+
+ DALI_TEST_CHECK( colorIndicesBuffer2 );
+
+ //default color
+ DALI_TEST_EQUALS( colorIndicesBuffer2[0], 0u, TEST_LOCATION);
+
+ //default color
+ DALI_TEST_EQUALS( colorIndicesBuffer2[1], 0u, TEST_LOCATION);
+
+ //span color
+ DALI_TEST_EQUALS( colorIndicesBuffer2[6], 1u, TEST_LOCATION);
+
+ //default color
+ DALI_TEST_EQUALS( colorIndicesBuffer2[7], 0u, TEST_LOCATION);
+
+ END_TEST;
}
\ No newline at end of file
${toolkit_src_dir}/text/markup-processor-anchor.cpp
${toolkit_src_dir}/text/markup-processor-font.cpp
${toolkit_src_dir}/text/markup-processor-background.cpp
+ ${toolkit_src_dir}/text/markup-processor-span.cpp
${toolkit_src_dir}/text/markup-processor-helper-functions.cpp
${toolkit_src_dir}/text/multi-language-support.cpp
${toolkit_src_dir}/text/hidden-text.cpp
const std::string XHTML_VALUE_ATTRIBUTE("value");
}
+void ProcessColor(const Attribute& attribute, ColorRun& colorRun)
+{
+ ColorStringToVector4(attribute.valueBuffer, attribute.valueLength, colorRun.color);
+}
+
void ProcessColorTag(const Tag& tag, ColorRun& colorRun)
{
for(Vector<Attribute>::ConstIterator it = tag.attributes.Begin(),
const Attribute& attribute(*it);
if(TokenComparison(XHTML_VALUE_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength))
{
- ColorStringToVector4(attribute.valueBuffer, attribute.valueLength, colorRun.color);
+ ProcessColor(attribute, colorRun);
}
}
}
namespace Text
{
struct Tag;
+struct Attribute;
struct ColorRun;
/**
* @brief Retrieves the color value from the tag and sets it to the color run.
*
+ * @param[in] attribute the color attribute.
+ * @param[in,out] colorRun The color run.
+ */
+void ProcessColor(const Attribute& attribute, ColorRun& colorRun);
+
+/**
+ * @brief Retrieves the color value from the tag and sets it to the color run.
+ *
* @param[in] tag The color tag and its attributes.
* @param[in,out] colorRun The color run.
*/
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.
+const std::string FONT_PREFIX("font-");
+const unsigned int FONT_PREFIX_LENGTH = 5u;
+const unsigned int MIN_FONT_ATTRIBUTE_SIZE = 4u; ///< The minimum length of any of the possible 'weight', 'width' , 'slant' or 'size' values.
+const unsigned int MAX_FONT_ATTRIBUTE_SIZE = 15u; ///< The maximum length of any of the possible 'weight', 'width' or 'slant' values.
+const float PIXEL_FORMAT_64_FACTOR = 64.f; ///< 64.f is used to convert from point size to 26.6 pixel format.
} // namespace
+void processFontAttributeValue(char value[], const Attribute& attribute)
+{
+ // The StringToWeight() uses the Scripting::GetEnumeration() function which requires the input string to end with a '\0' char.
+ const Length length = attribute.valueLength > MAX_FONT_ATTRIBUTE_SIZE ? MAX_FONT_ATTRIBUTE_SIZE : attribute.valueLength;
+ memcpy(value, attribute.valueBuffer, length);
+ value[length] = 0;
+}
+
+void ProcessFontFamily(const Attribute& attribute, FontDescriptionRun& fontRun)
+{
+ 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.
+}
+
+void ProcessFontSize(const Attribute& attribute, FontDescriptionRun& fontRun)
+{
+ // 64.f is used to convert from point size to 26.6 pixel format.
+ fontRun.size = static_cast<PointSize26Dot6>(StringToFloat(attribute.valueBuffer) * PIXEL_FORMAT_64_FACTOR);
+ fontRun.sizeDefined = true;
+}
+
+void ProcessFontWeight(const Attribute& attribute, FontDescriptionRun& fontRun)
+{
+ char value[MAX_FONT_ATTRIBUTE_SIZE + 1u];
+ processFontAttributeValue(value, attribute);
+
+ fontRun.weight = StringToWeight(value);
+ fontRun.weightDefined = true;
+}
+
+void ProcessFontWidth(const Attribute& attribute, FontDescriptionRun& fontRun)
+{
+ char value[MAX_FONT_ATTRIBUTE_SIZE + 1u];
+ processFontAttributeValue(value, attribute);
+
+ fontRun.width = StringToWidth(value);
+ fontRun.widthDefined = true;
+}
+
+void ProcessFontSlant(const Attribute& attribute, FontDescriptionRun& fontRun)
+{
+ char value[MAX_FONT_ATTRIBUTE_SIZE + 1u];
+ processFontAttributeValue(value, attribute);
+
+ fontRun.slant = StringToSlant(value);
+ fontRun.slantDefined = true;
+}
+
void ProcessFontTag(const Tag& tag, FontDescriptionRun& fontRun)
{
for(Vector<Attribute>::ConstIterator it = tag.attributes.Begin(),
++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.
+ ProcessFontFamily(attribute, fontRun);
}
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;
+ ProcessFontSize(attribute, fontRun);
}
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;
+ ProcessFontWeight(attribute, fontRun);
}
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;
+ ProcessFontWidth(attribute, fontRun);
}
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;
+ ProcessFontSlant(attribute, fontRun);
}
}
}
namespace Text
{
struct Tag;
+struct Attribute;
struct FontDescriptionRun;
/**
*/
void ProcessFontTag(const Tag& tag, FontDescriptionRun& fontRun);
+/**
+ * @brief Fill the font run with the font slant attribute value.
+ *
+ * @param[in] attribute the font slant attribute.
+ * @param[out] fontRun The font description run.
+ */
+void ProcessFontSlant(const Attribute& attribute, FontDescriptionRun& fontRun);
+
+/**
+ * @brief Fill the font run with the font width attribute value.
+ *
+ * @param[in] attribute the font width attribute.
+ * @param[out] fontRun The font description run.
+ */
+void ProcessFontWidth(const Attribute& attribute, FontDescriptionRun& fontRun);
+
+/**
+ * @brief Fill the font run with the font weight attribute value.
+ *
+ * @param[in] attribute the font weight attribute.
+ * @param[out] fontRun The font description run.
+ */
+void ProcessFontWeight(const Attribute& attribute, FontDescriptionRun& fontRun);
+
+/**
+ * @brief Fill the font run with the font size attribute value.
+ *
+ * @param[in] attribute the font size attribute.
+ * @param[out] fontRun The font description run.
+ */
+void ProcessFontSize(const Attribute& attribute, FontDescriptionRun& fontRun);
+
+/**
+ * @brief Fill the font run with the font family attribute value.
+ *
+ * @param[in] attribute the font family attribute.
+ * @param[out] fontRun The font description run.
+ */
+void ProcessFontFamily(const Attribute& attribute, FontDescriptionRun& fontRun);
+
} // namespace Text
} // namespace Toolkit
--- /dev/null
+/*
+ * 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-color.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/dali-vector.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/color-run.h>
+#include <dali-toolkit/internal/text/font-description-run.h>
+#include <dali-toolkit/internal/text/markup-processor-font.h>
+#include <dali-toolkit/internal/text/markup-processor-helper-functions.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+namespace
+{
+const std::string XHTML_FAMILY_ATTRIBUTE("font-family");
+const std::string XHTML_SIZE_ATTRIBUTE("font-size");
+const std::string XHTML_WEIGHT_ATTRIBUTE("font-weight");
+const std::string XHTML_WIDTH_ATTRIBUTE("font-width");
+const std::string XHTML_SLANT_ATTRIBUTE("font-slant");
+
+const std::string XHTML_COLOR_ATTRIBUTE("text-color");
+} // namespace
+
+void ProcessSpanTag(const Tag& tag, ColorRun& colorRun, FontDescriptionRun& fontRun, bool& isColorDefined, bool& isFontDefined)
+{
+ for(Vector<Attribute>::ConstIterator it = tag.attributes.Begin(),
+ endIt = tag.attributes.End();
+ it != endIt;
+ ++it)
+ {
+ const Attribute& attribute(*it);
+
+ if(TokenComparison(XHTML_COLOR_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength))
+ {
+ isColorDefined = true;
+ ProcessColor(attribute, colorRun);
+ }
+ else if(TokenComparison(XHTML_FAMILY_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength))
+ {
+ isFontDefined = true;
+ ProcessFontFamily(attribute, fontRun);
+ }
+ else if(TokenComparison(XHTML_SIZE_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength))
+ {
+ isFontDefined = true;
+ ProcessFontSize(attribute, fontRun);
+ }
+ else if(TokenComparison(XHTML_WEIGHT_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength))
+ {
+ isFontDefined = true;
+ ProcessFontWeight(attribute, fontRun);
+ }
+ else if(TokenComparison(XHTML_WIDTH_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength))
+ {
+ isFontDefined = true;
+ ProcessFontWidth(attribute, fontRun);
+ }
+ else if(TokenComparison(XHTML_SLANT_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength))
+ {
+ isFontDefined = true;
+ ProcessFontSlant(attribute, fontRun);
+ }
+ }
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_SPAN_H
+#define DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_SPAN_H
+
+/*
+ * Copyright (c) 2021 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 MarkupProcessData;
+
+/**
+ * @brief process the span from the tag and process all styles in it.
+ *
+ * @param[in] tag The span tag and its attributes.
+ * @param[out] colorRun the color run to be filled.
+ * @param[out] fontRun the font run to be filled.
+ * @param[out] isColorDefined if the span has color defined.
+ * @param[out] isFontDefined if the span has font defined.
+ */
+void ProcessSpanTag(const Tag& tag, ColorRun& colorRun, FontDescriptionRun& fontRun, bool& isColorDefined, bool& isFontDefined);
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_SPAN_H
#include <dali-toolkit/internal/text/markup-processor-embedded-item.h>
#include <dali-toolkit/internal/text/markup-processor-font.h>
#include <dali-toolkit/internal/text/markup-processor-helper-functions.h>
+#include <dali-toolkit/internal/text/markup-processor-span.h>
#include <dali-toolkit/internal/text/xhtml-entities.h>
namespace Dali
const std::string XHTML_ITEM_TAG("item");
const std::string XHTML_ANCHOR_TAG("a");
const std::string XHTML_BACKGROUND_TAG("background");
+const std::string XHTML_SPAN_TAG("span");
const char LESS_THAN = '<';
const char GREATER_THAN = '>';
Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_MARKUP_PROCESSOR");
#endif
+typedef VectorBase::SizeType RunIndex;
+
/**
* @brief Struct used to retrieve the style runs from the mark-up string.
*/
+template<typename StyleStackType>
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.
+ Vector<StyleStackType> stack; ///< Use a vector as a style stack.
+ unsigned int topIndex; ///< Points the top of the stack.
StyleStack()
: stack(),
stack.Resize(DEFAULT_VECTOR_SIZE);
}
- void Push(RunIndex index)
+ void Push(StyleStackType item)
{
// Check if there is space inside the style stack.
const VectorBase::SizeType size = stack.Count();
stack.Resize(2u * size);
}
- // Set the run index in the top of the stack.
- *(stack.Begin() + topIndex) = index;
+ // Set the item in the top of the stack.
+ *(stack.Begin() + topIndex) = item;
// Reposition the pointer to the top of the stack.
++topIndex;
}
- RunIndex Pop()
+ StyleStackType Pop()
{
// Pop the top of the stack.
--topIndex;
};
/**
+ * @brief Struct used to retrieve spans from the mark-up string.
+ */
+struct Span
+{
+ RunIndex colorRunIndex;
+ RunIndex fontRunIndex;
+ bool isColorDefined;
+ bool isFontDefined;
+};
+
+/**
* @brief Initializes a font run description to its defaults.
*
* @param[in,out] fontRun The font description run to initialize.
}
/**
+ * @brief Initializes a span to its defaults.
+ *
+ * @param[in,out] span The span to be initialized.
+ */
+void Initialize(Span& span)
+{
+ span.colorRunIndex = 0u;
+ span.isColorDefined = false;
+ span.fontRunIndex = 0u;
+ span.isFontDefined = false;
+}
+
+/**
* @brief Splits the tag string into the tag name and its attributes.
*
* The attributes are stored in a vector in the tag.
template<typename RunType>
void ProcessTagForRun(
Vector<RunType>& runsContainer,
- StyleStack& styleStack,
+ StyleStack<RunIndex>& styleStack,
const Tag& tag,
const CharacterIndex characterIndex,
- StyleStack::RunIndex& runIndex,
+ RunIndex& runIndex,
int& tagReference,
std::function<void(const Tag&, RunType&)> parameterSettingFunction)
{
}
/**
+ * @brief Processes span tag for the color-run & font-run.
+ *
+ * @param[in] spanTag The tag we are currently processing
+ * @param[in/out] spanStack The spans stack
+ * @param[int/out] colorRuns The container containing all the color runs
+ * @param[int/out] fontRuns The container containing all the font description runs
+ * @param[in/out] colorRunIndex The color run index
+ * @param[in/out] fontRunIndex The font run index
+ * @param[in] characterIndex The current character index
+ * @param[in] tagReference The tagReference we should increment/decrement
+ */
+void ProcessSpanForRun(
+ const Tag& spanTag,
+ StyleStack<Span>& spanStack,
+ Vector<ColorRun>& colorRuns,
+ Vector<FontDescriptionRun>& fontRuns,
+ RunIndex& colorRunIndex,
+ RunIndex& fontRunIndex,
+ const CharacterIndex characterIndex,
+ int& tagReference)
+{
+ if(!spanTag.isEndTag)
+ {
+ // Create a new run.
+ ColorRun colorRun;
+ Initialize(colorRun);
+
+ FontDescriptionRun fontRun;
+ Initialize(fontRun);
+
+ Span span;
+ Initialize(span);
+
+ // Fill the run with the parameters.
+ colorRun.characterRun.characterIndex = characterIndex;
+ fontRun.characterRun.characterIndex = characterIndex;
+
+ span.colorRunIndex = colorRunIndex;
+ span.fontRunIndex = fontRunIndex;
+
+ ProcessSpanTag(spanTag, colorRun, fontRun, span.isColorDefined, span.isFontDefined);
+
+ // Push the span into the stack.
+ spanStack.Push(span);
+
+ // Point the next free run.
+ if(span.isColorDefined)
+ {
+ // Push the run in the logical model.
+ colorRuns.PushBack(colorRun);
+ ++colorRunIndex;
+ }
+
+ if(span.isFontDefined)
+ {
+ // Push the run in the logical model.
+ fontRuns.PushBack(fontRun);
+ ++fontRunIndex;
+ }
+
+ // Increase reference
+ ++tagReference;
+ }
+ else
+ {
+ if(tagReference > 0)
+ {
+ // Pop the top of the stack and set the number of characters of the run.
+ Span span = spanStack.Pop();
+
+ if(span.isColorDefined)
+ {
+ ColorRun& colorRun = *(colorRuns.Begin() + span.colorRunIndex);
+ colorRun.characterRun.numberOfCharacters = characterIndex - colorRun.characterRun.characterIndex;
+ }
+
+ if(span.isFontDefined)
+ {
+ FontDescriptionRun& fontRun = *(fontRuns.Begin() + span.fontRunIndex);
+ fontRun.characterRun.numberOfCharacters = characterIndex - fontRun.characterRun.characterIndex;
+ }
+
+ --tagReference;
+ }
+ }
+}
+
+/**
* @brief Resizes the model's vectors
*
* @param[in/out] markupProcessData The markup process data
* @param[in] underlinedCharacterRunIndex The underlined character run index
* @param[in] backgroundRunIndex The background run index
*/
-void ResizeModelVectors(MarkupProcessData& markupProcessData, const StyleStack::RunIndex fontRunIndex, const StyleStack::RunIndex colorRunIndex, const StyleStack::RunIndex underlinedCharacterRunIndex, const StyleStack::RunIndex backgroundRunIndex)
+void ResizeModelVectors(MarkupProcessData& markupProcessData, const RunIndex fontRunIndex, const RunIndex colorRunIndex, const RunIndex underlinedCharacterRunIndex, const RunIndex backgroundRunIndex)
{
markupProcessData.fontRuns.Resize(fontRunIndex);
markupProcessData.colorRuns.Resize(colorRunIndex);
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;
+ StyleStack<RunIndex> styleStack;
+
+ // Stores a struct with the index to the first character of the color run & color font for the span.
+ StyleStack<Span> spanStack;
// Points the next free position in the vector of runs.
- StyleStack::RunIndex colorRunIndex = 0u;
- StyleStack::RunIndex fontRunIndex = 0u;
- StyleStack::RunIndex underlinedCharacterRunIndex = 0u;
- StyleStack::RunIndex backgroundRunIndex = 0u;
+ RunIndex colorRunIndex = 0u;
+ RunIndex fontRunIndex = 0u;
+ RunIndex underlinedCharacterRunIndex = 0u;
+ RunIndex backgroundRunIndex = 0u;
// check tag reference
int colorTagReference = 0u;
int bTagReference = 0u;
int uTagReference = 0u;
int backgroundTagReference = 0u;
+ int spanTagReference = 0u;
// Give an initial default value to the model's vectors.
markupProcessData.colorRuns.Reserve(DEFAULT_VECTOR_SIZE);
ProcessTagForRun<ColorRun>(
markupProcessData.backgroundColorRuns, styleStack, tag, characterIndex, backgroundRunIndex, backgroundTagReference, [](const Tag& tag, ColorRun& run) { ProcessBackground(tag, run); });
}
+ else if(TokenComparison(XHTML_SPAN_TAG, tag.buffer, tag.length))
+ {
+ ProcessSpanForRun(tag, spanStack, markupProcessData.colorRuns, markupProcessData.fontRuns, colorRunIndex, fontRunIndex, characterIndex, spanTagReference);
+ }
} // end if( IsTag() )
else if(markupStringBuffer < markupStringEndBuffer)
{