Add Character-Spacing value attribute "char-space-value" to span tag.
How to apply it in TextEditor:
textEditor.SetProperty(Dali::Toolkit::TextEditor::Property::TEXT,
"<span font-size='20' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='blue' >ABC EF\n</span>"
"<span font-size='20' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' char-space-value='-5.0f'>ABC EF\n</span>"
"<span font-size='20' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='green' char-space-value='10.0f'>ABC EF\n</span>");
textEditor.SetProperty(Dali::Toolkit::TextEditor::Property::ENABLE_MARKUP, true);
This patch should be preceded by the patch below:
https://review.tizen.org/gerrit/c/platform/core/uifw/dali-toolkit/+/271789
Change-Id: I203c6e1f3a116ae557ffbc84859a121739e6b6c6
DALI_TEST_EQUALS(diffLineExpandedCharSpacing, diffLineNoCharSpacing + expandedCharSpacing, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
}
+ END_TEST;
+}
+
+int UtcDaliTextEditorMarkupSpanCharacterSpacing(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliTextEditorMarkupSpanCharacterSpacing ");
+
+ const Length EXPECTED_NUMBER_OF_GLYPHS = 21u;
+
+ const float expandedCharSpacing = 10.0f;
+ const float condensedCharSpacing = -5.0f;
+
+ std::string testText =
+ "<span font-size='20' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='blue' >ABC EF\n</span>"
+ "<span font-size='20' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' char-space-value='-5.0f'>ABC EF\n</span>"
+ "<span font-size='20' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='green' char-space-value='10.0f'>ABC EF\n</span>";
+
+ TextEditor textEditor = TextEditor::New();
+
+ textEditor.SetProperty(TextEditor::Property::TEXT, testText);
+ textEditor.SetProperty(TextEditor ::Property::ENABLE_MARKUP, true);
+
+ application.GetScene().Add(textEditor);
+
+ application.SendNotification();
+ application.Render();
+
+ Toolkit::Internal::TextEditor& textEditorImpl = GetImpl(textEditor);
+ Text::ViewInterface& view = textEditorImpl.GetTextController()->GetView();
+
+ Length numberOfGlyphs = view.GetNumberOfGlyphs();
+
+ DALI_TEST_EQUALS(numberOfGlyphs, EXPECTED_NUMBER_OF_GLYPHS, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
+
+ Vector<GlyphInfo> glyphs;
+ glyphs.Resize(numberOfGlyphs);
+
+ Vector<Vector2> positions;
+ positions.Resize(numberOfGlyphs);
+
+ float alignmentOffset = 0u;
+ numberOfGlyphs = view.GetGlyphs(glyphs.Begin(),
+ positions.Begin(),
+ alignmentOffset,
+ 0u,
+ numberOfGlyphs);
+
+ const Length numberOfGlyphsOneLine = 7u;
+ for(Length i = 0; i < numberOfGlyphsOneLine - 1u; i++)
+ {
+ float diffLineNoCharSpacing = positions[i + 1].x - positions[i].x;
+
+ float diffLineCondensedCharSpacing = positions[numberOfGlyphsOneLine + i + 1].x - positions[numberOfGlyphsOneLine + i].x;
+ DALI_TEST_EQUALS(diffLineCondensedCharSpacing, diffLineNoCharSpacing + condensedCharSpacing, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
+
+ float diffLineExpandedCharSpacing = positions[2u * numberOfGlyphsOneLine + i + 1].x - positions[2u * numberOfGlyphsOneLine + i].x;
+ DALI_TEST_EQUALS(diffLineExpandedCharSpacing, diffLineNoCharSpacing + expandedCharSpacing, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
+ }
+
END_TEST;
}
\ No newline at end of file
DALI_TEST_EQUALS(diffLineExpandedCharSpacing, diffLineNoCharSpacing + expandedCharSpacing, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
}
+ END_TEST;
+}
+
+int UtcDaliTextFieldMarkupSpanCharacterSpacing(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliTextFieldMarkupSpanCharacterSpacing ");
+
+ const Length EXPECTED_NUMBER_OF_GLYPHS = 21u;
+
+ const float expandedCharSpacing = 10.0f;
+ const float condensedCharSpacing = -5.0f;
+
+ std::string testText =
+ "<span font-size='20' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='blue' >ABC EF\n</span>"
+ "<span font-size='20' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' char-space-value='-5.0f'>ABC EF\n</span>"
+ "<span font-size='20' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='green' char-space-value='10.0f'>ABC EF\n</span>";
+
+ TextField textField = TextField::New();
+
+ textField.SetProperty(TextField::Property::TEXT, testText);
+ textField.SetProperty(TextField ::Property::ENABLE_MARKUP, true);
+
+ application.GetScene().Add(textField);
+
+ application.SendNotification();
+ application.Render();
+
+ Toolkit::Internal::TextField& textFieldImpl = GetImpl(textField);
+ Text::ViewInterface& view = textFieldImpl.GetTextController()->GetView();
+
+ Length numberOfGlyphs = view.GetNumberOfGlyphs();
+
+ DALI_TEST_EQUALS(numberOfGlyphs, EXPECTED_NUMBER_OF_GLYPHS, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
+
+ Vector<GlyphInfo> glyphs;
+ glyphs.Resize(numberOfGlyphs);
+
+ Vector<Vector2> positions;
+ positions.Resize(numberOfGlyphs);
+
+ float alignmentOffset = 0u;
+ numberOfGlyphs = view.GetGlyphs(glyphs.Begin(),
+ positions.Begin(),
+ alignmentOffset,
+ 0u,
+ numberOfGlyphs);
+
+ const Length numberOfGlyphsOneLine = 7u;
+ for(Length i = 0; i < numberOfGlyphsOneLine - 1u; i++)
+ {
+ float diffLineNoCharSpacing = positions[i + 1].x - positions[i].x;
+
+ float diffLineCondensedCharSpacing = positions[numberOfGlyphsOneLine + i + 1].x - positions[numberOfGlyphsOneLine + i].x;
+ DALI_TEST_EQUALS(diffLineCondensedCharSpacing, diffLineNoCharSpacing + condensedCharSpacing, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
+
+ float diffLineExpandedCharSpacing = positions[2u * numberOfGlyphsOneLine + i + 1].x - positions[2u * numberOfGlyphsOneLine + i].x;
+ DALI_TEST_EQUALS(diffLineExpandedCharSpacing, diffLineNoCharSpacing + expandedCharSpacing, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
+ }
+
END_TEST;
}
\ No newline at end of file
DALI_TEST_EQUALS(diffLineExpandedCharSpacing, diffLineNoCharSpacing + expandedCharSpacing, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
}
+ END_TEST;
+}
+
+int UtcDaliTextLabelMarkupSpanCharacterSpacing(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliTextLabelMarkupSpanCharacterSpacing ");
+
+ const Length EXPECTED_NUMBER_OF_GLYPHS = 21u;
+
+ const float expandedCharSpacing = 10.0f;
+ const float condensedCharSpacing = -5.0f;
+
+ std::string testText =
+ "<span font-size='20' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='blue' >ABC EF\n</span>"
+ "<span font-size='20' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='red' char-space-value='-5.0f'>ABC EF\n</span>"
+ "<span font-size='20' font-family='DejaVu Sans' font-width='condensed' font-slant='italic' text-color='green' char-space-value='10.0f'>ABC EF\n</span>";
+
+ TextLabel textLabel = TextLabel::New();
+
+ textLabel.SetProperty(TextLabel::Property::TEXT, testText);
+ textLabel.SetProperty(TextLabel ::Property::ENABLE_MARKUP, true);
+ textLabel.SetProperty(TextLabel::Property::MULTI_LINE, true);
+
+ application.GetScene().Add(textLabel);
+
+ application.SendNotification();
+ application.Render();
+
+ Toolkit::Internal::TextLabel& textLabelImpl = GetImpl(textLabel);
+ Text::ViewInterface& view = textLabelImpl.GetTextController()->GetView();
+
+ Length numberOfGlyphs = view.GetNumberOfGlyphs();
+
+ DALI_TEST_EQUALS(numberOfGlyphs, EXPECTED_NUMBER_OF_GLYPHS, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
+
+ Vector<GlyphInfo> glyphs;
+ glyphs.Resize(numberOfGlyphs);
+
+ Vector<Vector2> positions;
+ positions.Resize(numberOfGlyphs);
+
+ float alignmentOffset = 0u;
+ numberOfGlyphs = view.GetGlyphs(glyphs.Begin(),
+ positions.Begin(),
+ alignmentOffset,
+ 0u,
+ numberOfGlyphs);
+
+ const Length numberOfGlyphsOneLine = 7u;
+ for(Length i = 0; i < numberOfGlyphsOneLine - 1u; i++)
+ {
+ float diffLineNoCharSpacing = positions[i + 1].x - positions[i].x;
+
+ float diffLineCondensedCharSpacing = positions[numberOfGlyphsOneLine + i + 1].x - positions[numberOfGlyphsOneLine + i].x;
+ DALI_TEST_EQUALS(diffLineCondensedCharSpacing, diffLineNoCharSpacing + condensedCharSpacing, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
+
+ float diffLineExpandedCharSpacing = positions[2u * numberOfGlyphsOneLine + i + 1].x - positions[2u * numberOfGlyphsOneLine + i].x;
+ DALI_TEST_EQUALS(diffLineExpandedCharSpacing, diffLineNoCharSpacing + expandedCharSpacing, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
+ }
+
END_TEST;
}
\ No newline at end of file
// 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-character-spacing.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-strikethrough.h>
const std::string XHTML_STRIKETHROUGH_COLOR_ATTRIBUTE("s-color");
const std::string XHTML_STRIKETHROUGH_HEIGHT_ATTRIBUTE("s-height");
-} // namespace
+//the character-spacing character's attributes
+const std::string XHTML_CHARACTER_SPACING_VALUE_ATTRIBUTE("char-space-value");
+
+//NOTE: the MAX_NUM_OF_ATTRIBUTES in "markup-processor.cpp" should be updated when add a new attribute for span tag.
-void ProcessSpanTag(const Tag& tag,
- ColorRun& colorRun,
- FontDescriptionRun& fontRun,
- UnderlinedCharacterRun& underlinedCharacterRun,
- ColorRun& backgroundColorRun,
- StrikethroughCharacterRun& strikethroughRun,
- bool& isColorDefined,
- bool& isFontDefined,
- bool& isUnderlinedCharacterDefined,
- bool& isBackgroundColorDefined,
- bool& isStrikethroughDefined)
+} // namespace
+void ProcessSpanTag(const Tag& tag,
+ ColorRun& colorRun,
+ FontDescriptionRun& fontRun,
+ UnderlinedCharacterRun& underlinedCharacterRun,
+ ColorRun& backgroundColorRun,
+ StrikethroughCharacterRun& strikethroughRun,
+ CharacterSpacingCharacterRun& characterSpacingCharacterRun,
+ bool& isColorDefined,
+ bool& isFontDefined,
+ bool& isUnderlinedCharacterDefined,
+ bool& isBackgroundColorDefined,
+ bool& isStrikethroughDefined,
+ bool& isCharacterSpacingDefined)
{
for(Vector<Attribute>::ConstIterator it = tag.attributes.Begin(),
endIt = tag.attributes.End();
isStrikethroughDefined = true;
ProcessHeightAttribute(attribute, strikethroughRun);
}
+ else if(TokenComparison(XHTML_CHARACTER_SPACING_VALUE_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength))
+ {
+ isCharacterSpacingDefined = true;
+ ProcessValueAttribute(attribute, characterSpacingCharacterRun);
+ }
}
}
* @param[out] underlinedCharacterRun the underlined character run to be filled.
* @param[out] backgroundColorRun the background color run to be filled.
* @param[out] strikethroughRun the strikethrough run to be filled.
+ * @param[out] characterSpacingCharacterRun the character-spacing run to be filled.
* @param[out] isColorDefined if the span has color defined.
* @param[out] isFontDefined if the span has font defined.
* @param[out] isUnderlinedCharacterDefined if the span has underlined-character defined.
* @param[out] isBackgroundColorDefined if the span has background color defined.
* @param[out] isStrikethroughDefined if the span has strikethrough defined.
+ * @param[out] isCharacterSpacingDefined if the span has character-spacing defined.
*/
-void ProcessSpanTag(const Tag& tag,
- ColorRun& colorRun,
- FontDescriptionRun& fontRun,
- UnderlinedCharacterRun& underlinedCharacterRun,
- ColorRun& backgroundColorRun,
- StrikethroughCharacterRun& strikethroughRun,
- bool& isColorDefined,
- bool& isFontDefined,
- bool& isUnderlinedCharacterDefined,
- bool& isBackgroundColorDefined,
- bool& isStrikethroughDefined);
+void ProcessSpanTag(const Tag& tag,
+ ColorRun& colorRun,
+ FontDescriptionRun& fontRun,
+ UnderlinedCharacterRun& underlinedCharacterRun,
+ ColorRun& backgroundColorRun,
+ StrikethroughCharacterRun& strikethroughRun,
+ CharacterSpacingCharacterRun& characterSpacingCharacterRun,
+ bool& isColorDefined,
+ bool& isFontDefined,
+ bool& isUnderlinedCharacterDefined,
+ bool& isBackgroundColorDefined,
+ bool& isStrikethroughDefined,
+ bool& isCharacterSpacingDefined);
} // namespace Text
// Range 3 0x10000u < XHTML_DECIMAL_ENTITY_RANGE <= 0x10FFFFu
const unsigned long XHTML_DECIMAL_ENTITY_RANGE[] = {0x0u, 0xD7FFu, 0xE000u, 0xFFFDu, 0x10000u, 0x10FFFFu};
-const unsigned int MAX_NUM_OF_ATTRIBUTES = 13u; ///< The span tag has the 'font-family', 'font-size' 'font-weight', 'font-width', 'font-slant','text-color', 'u-color', 'u-height','u-type','u-dash-gap', 'u-dash-width', 's-color' and 's-height' attrubutes.
+// The MAX_NUM_OF_ATTRIBUTES is the number of attributes in span tag "markup-processor-span.cpp". Because it contains the maximum number of attributes in all tags.
+const unsigned int MAX_NUM_OF_ATTRIBUTES = 14u; ///< The span tag has the 'font-family', 'font-size' 'font-weight', 'font-width', 'font-slant','text-color', 'u-color', 'u-height','u-type','u-dash-gap', 'u-dash-width', 's-color', 's-height' and 'char-space-value' attrubutes.
const unsigned int DEFAULT_VECTOR_SIZE = 16u; ///< Default size of run vectors.
#if defined(DEBUG_ENABLED)
RunIndex underlinedCharacterRunIndex;
RunIndex backgroundColorRunIndex;
RunIndex strikethroughCharacterRunIndex;
+ RunIndex characterSpacingCharacterRunIndex;
bool isColorDefined;
bool isFontDefined;
bool isUnderlinedCharacterDefined;
bool isBackgroundColorDefined;
bool isStrikethroughDefined;
+ bool isCharacterSpacingDefined;
};
/**
*/
void Initialize(Span& span)
{
- span.colorRunIndex = 0u;
- span.isColorDefined = false;
- span.fontRunIndex = 0u;
- span.isFontDefined = false;
+ span.colorRunIndex = 0u;
+ span.isColorDefined = false;
+
+ span.fontRunIndex = 0u;
+ span.isFontDefined = false;
+
span.underlinedCharacterRunIndex = 0u;
span.isUnderlinedCharacterDefined = false;
span.backgroundColorRunIndex = 0u;
//strikethrough
span.strikethroughCharacterRunIndex = 0u;
span.isStrikethroughDefined = false;
+
+ //characterSpacing
+ span.characterSpacingCharacterRunIndex = 0u;
+ span.isCharacterSpacingDefined = false;
}
/**
* @param[in] tagReference The tagReference we should increment/decrement
*/
void ProcessSpanForRun(
- const Tag& spanTag,
- StyleStack<Span>& spanStack,
- Vector<ColorRun>& colorRuns,
- Vector<FontDescriptionRun>& fontRuns,
- Vector<UnderlinedCharacterRun>& underlinedCharacterRuns,
- Vector<ColorRun>& backgroundColorRuns,
- Vector<StrikethroughCharacterRun>& strikethroughCharacterRuns,
- RunIndex& colorRunIndex,
- RunIndex& fontRunIndex,
- RunIndex& underlinedCharacterRunIndex,
- RunIndex& backgroundColorRunIndex,
- RunIndex& strikethroughCharacterRunIndex,
- const CharacterIndex characterIndex,
- int& tagReference)
+ const Tag& spanTag,
+ StyleStack<Span>& spanStack,
+ Vector<ColorRun>& colorRuns,
+ Vector<FontDescriptionRun>& fontRuns,
+ Vector<UnderlinedCharacterRun>& underlinedCharacterRuns,
+ Vector<ColorRun>& backgroundColorRuns,
+ Vector<StrikethroughCharacterRun>& strikethroughCharacterRuns,
+ Vector<CharacterSpacingCharacterRun>& characterSpacingCharacterRuns,
+ RunIndex& colorRunIndex,
+ RunIndex& fontRunIndex,
+ RunIndex& underlinedCharacterRunIndex,
+ RunIndex& backgroundColorRunIndex,
+ RunIndex& strikethroughCharacterRunIndex,
+ RunIndex& characterSpacingCharacterRunIndex,
+ const CharacterIndex characterIndex,
+ int& tagReference)
{
if(!spanTag.isEndTag)
{
StrikethroughCharacterRun strikethroughCharacterRun;
Initialize(strikethroughCharacterRun);
+ CharacterSpacingCharacterRun characterSpacingCharacterRun;
+ Initialize(characterSpacingCharacterRun);
+
Span span;
Initialize(span);
// Fill the run with the parameters.
- colorRun.characterRun.characterIndex = characterIndex;
- fontRun.characterRun.characterIndex = characterIndex;
- underlinedCharacterRun.characterRun.characterIndex = characterIndex;
- backgroundColorRun.characterRun.characterIndex = characterIndex;
- strikethroughCharacterRun.characterRun.characterIndex = characterIndex;
-
- span.colorRunIndex = colorRunIndex;
- span.fontRunIndex = fontRunIndex;
- span.underlinedCharacterRunIndex = underlinedCharacterRunIndex;
- span.backgroundColorRunIndex = backgroundColorRunIndex;
- span.strikethroughCharacterRunIndex = strikethroughCharacterRunIndex;
+ colorRun.characterRun.characterIndex = characterIndex;
+ fontRun.characterRun.characterIndex = characterIndex;
+ underlinedCharacterRun.characterRun.characterIndex = characterIndex;
+ backgroundColorRun.characterRun.characterIndex = characterIndex;
+ strikethroughCharacterRun.characterRun.characterIndex = characterIndex;
+ characterSpacingCharacterRun.characterRun.characterIndex = characterIndex;
+
+ span.colorRunIndex = colorRunIndex;
+ span.fontRunIndex = fontRunIndex;
+ span.underlinedCharacterRunIndex = underlinedCharacterRunIndex;
+ span.backgroundColorRunIndex = backgroundColorRunIndex;
+ span.strikethroughCharacterRunIndex = strikethroughCharacterRunIndex;
+ span.characterSpacingCharacterRunIndex = characterSpacingCharacterRunIndex;
ProcessSpanTag(spanTag,
colorRun,
underlinedCharacterRun,
backgroundColorRun,
strikethroughCharacterRun,
+ characterSpacingCharacterRun,
span.isColorDefined,
span.isFontDefined,
span.isUnderlinedCharacterDefined,
span.isBackgroundColorDefined,
- span.isStrikethroughDefined);
+ span.isStrikethroughDefined,
+ span.isCharacterSpacingDefined);
// Push the span into the stack.
spanStack.Push(span);
++strikethroughCharacterRunIndex;
}
+ if(span.isCharacterSpacingDefined)
+ {
+ // Push the run in the logical model.
+ characterSpacingCharacterRuns.PushBack(characterSpacingCharacterRun);
+ ++characterSpacingCharacterRunIndex;
+ }
+
// Increase reference
++tagReference;
}
strikethroughCharacterRun.characterRun.numberOfCharacters = characterIndex - strikethroughCharacterRun.characterRun.characterIndex;
}
+ if(span.isCharacterSpacingDefined)
+ {
+ CharacterSpacingCharacterRun& characterSpacingCharacterRun = *(characterSpacingCharacterRuns.Begin() + span.characterSpacingCharacterRunIndex);
+ characterSpacingCharacterRun.characterRun.numberOfCharacters = characterIndex - characterSpacingCharacterRun.characterRun.characterIndex;
+ }
+
--tagReference;
}
}
markupProcessData.underlinedCharacterRuns,
markupProcessData.backgroundColorRuns,
markupProcessData.strikethroughCharacterRuns,
+ markupProcessData.characterSpacingCharacterRuns,
colorRunIndex,
fontRunIndex,
underlinedCharacterRunIndex,
backgroundRunIndex,
strikethroughCharacterRunIndex,
+ characterSpacingCharacterRunIndex,
characterIndex,
spanTagReference);
}