END_TEST;
}
+int UtcDaliToolkitTextEditorMarkupRelativeLineHeight(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliToolkitTextEditorMarkupRelativeLineHeight");
+
+ TextEditor editor = TextEditor::New();
+ editor.SetProperty(Actor::Property::SIZE, Vector2(200.0f, 300.f));
+ editor.SetProperty(TextEditor::Property::POINT_SIZE, 10);
+ editor.SetProperty(TextEditor::Property::TEXT, "line 1\nline 2\nline 3\nline 4\nline 5");
+ editor.SetProperty(DevelTextEditor::Property::RELATIVE_LINE_SIZE, 1.0f);
+ editor.SetProperty(DevelTextEditor::Property::ELLIPSIS, false);
+ editor.SetProperty(TextEditor::Property::ENABLE_MARKUP, true);
+
+ TextEditor editorSingleLineParagraph = TextEditor::New();
+ editorSingleLineParagraph.SetProperty(Actor::Property::SIZE, Vector2(200.0f, 300.f));
+ editorSingleLineParagraph.SetProperty(TextEditor::Property::POINT_SIZE, 10);
+ editorSingleLineParagraph.SetProperty(TextEditor::Property::TEXT, "<p>line 1</p><p rel-line-height=0.5>line 2</p>line 3<p rel-line-height=3>line 4</p>line 5");
+ editorSingleLineParagraph.SetProperty(DevelTextEditor::Property::RELATIVE_LINE_SIZE, 1.0f);
+ editorSingleLineParagraph.SetProperty(DevelTextEditor::Property::ELLIPSIS, false);
+ editorSingleLineParagraph.SetProperty(TextEditor::Property::ENABLE_MARKUP, true);
+
+ TextEditor editorMultiLineParagraph = TextEditor::New();
+ editorMultiLineParagraph.SetProperty(Actor::Property::SIZE, Vector2(200.0f, 300.f));
+ editorMultiLineParagraph.SetProperty(TextEditor::Property::POINT_SIZE, 10);
+ editorMultiLineParagraph.SetProperty(TextEditor::Property::TEXT, "<p>line 1</p><p rel-line-height=0.5>line\n2</p>line 3<p rel-line-height=3>line\n4</p>line 5");
+ editorMultiLineParagraph.SetProperty(DevelTextEditor::Property::RELATIVE_LINE_SIZE, 1.0f);
+ editorMultiLineParagraph.SetProperty(DevelTextEditor::Property::ELLIPSIS, false);
+ editorMultiLineParagraph.SetProperty(TextEditor::Property::ENABLE_MARKUP, true);
+
+ application.GetScene().Add(editor);
+ application.GetScene().Add(editorSingleLineParagraph);
+ application.GetScene().Add(editorMultiLineParagraph);
+ application.SendNotification();
+ application.Render();
+
+ Vector3 naturalSize = editor.GetNaturalSize();
+ Vector3 relativeSingleNaturalSize = editorSingleLineParagraph.GetNaturalSize();
+ Vector3 relativeMultiNaturalSize = editorMultiLineParagraph.GetNaturalSize();
+
+ float lineSize = naturalSize.y / 5.0f; //total size/number of lines
+
+ //no effect of relative line size for paragraph with single line
+ DALI_TEST_EQUALS(naturalSize.y, relativeSingleNaturalSize.y, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
+
+ DALI_TEST_EQUALS(lineSize*8.5f, relativeMultiNaturalSize.y, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
+
+ END_TEST;
+}
+
int UtcDaliToolkitTextEditorRelativeLineHeight(void)
{
ToolkitTestApplication application;
END_TEST;
}
+int UtcDaliToolkitTextLabelMarkupRelativeLineHeight(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliToolkitTextLabelMarkupRelativeLineHeight");
+
+ TextLabel label = TextLabel::New();
+ label.SetProperty(Actor::Property::SIZE, Vector2(200.0f, 300.f));
+ label.SetProperty(TextLabel::Property::POINT_SIZE, 10);
+ label.SetProperty(TextLabel::Property::MULTI_LINE, true);
+ label.SetProperty(TextLabel::Property::TEXT, "line 1\nline 2\nline 3\nline 4\nline 5");
+ label.SetProperty(DevelTextLabel::Property::RELATIVE_LINE_SIZE, 1.0f);
+ label.SetProperty(TextLabel::Property::ELLIPSIS, false);
+ label.SetProperty(TextLabel::Property::ENABLE_MARKUP, true);
+
+ TextLabel labelSingleLineParagraph = TextLabel::New();
+ labelSingleLineParagraph.SetProperty(Actor::Property::SIZE, Vector2(200.0f, 300.f));
+ labelSingleLineParagraph.SetProperty(TextLabel::Property::POINT_SIZE, 10);
+ labelSingleLineParagraph.SetProperty(TextLabel::Property::MULTI_LINE, true);
+ labelSingleLineParagraph.SetProperty(TextLabel::Property::TEXT, "<p>line 1</p><p rel-line-height=0.5>line 2</p>line 3<p rel-line-height=3>line 4</p>line 5");
+ labelSingleLineParagraph.SetProperty(DevelTextLabel::Property::RELATIVE_LINE_SIZE, 1.0f);
+ labelSingleLineParagraph.SetProperty(TextLabel::Property::ELLIPSIS, false);
+ labelSingleLineParagraph.SetProperty(TextLabel::Property::ENABLE_MARKUP, true);
+
+ TextLabel labelMultiLineParagraph = TextLabel::New();
+ labelMultiLineParagraph.SetProperty(Actor::Property::SIZE, Vector2(200.0f, 300.f));
+ labelMultiLineParagraph.SetProperty(TextLabel::Property::POINT_SIZE, 10);
+ labelMultiLineParagraph.SetProperty(TextLabel::Property::MULTI_LINE, true);
+ labelMultiLineParagraph.SetProperty(TextLabel::Property::TEXT, "<p>line 1</p><p rel-line-height=0.5>line\n2</p>line 3<p rel-line-height=3>line\n4</p>line 5");
+ labelMultiLineParagraph.SetProperty(DevelTextLabel::Property::RELATIVE_LINE_SIZE, 1.0f);
+ labelMultiLineParagraph.SetProperty(TextLabel::Property::ELLIPSIS, false);
+ labelMultiLineParagraph.SetProperty(TextLabel::Property::ENABLE_MARKUP, true);
+
+ application.GetScene().Add(label);
+ application.GetScene().Add(labelSingleLineParagraph);
+ application.GetScene().Add(labelMultiLineParagraph);
+ application.SendNotification();
+ application.Render();
+
+ Vector3 naturalSize = label.GetNaturalSize();
+ Vector3 relativeSingleNaturalSize = labelSingleLineParagraph.GetNaturalSize();
+ Vector3 relativeMultiNaturalSize = labelMultiLineParagraph.GetNaturalSize();
+
+ float lineSize = naturalSize.y / 5.0f; //total size/number of lines
+
+ //no effect of relative line size for paragraph with single line
+ DALI_TEST_EQUALS(naturalSize.y, relativeSingleNaturalSize.y, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
+
+ DALI_TEST_EQUALS(lineSize*8.5f, relativeMultiNaturalSize.y, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
+
+ END_TEST;
+}
+
int UtcDaliToolkitTextLabelRelativeLineHeight(void)
{
ToolkitTestApplication application;
BoundedParagraphRun()
: characterRun{},
horizontalAlignment(Text::HorizontalAlignment::BEGIN),
- horizontalAlignmentDefined{false}
+ relativeLineSize(1),
+ horizontalAlignmentDefined{false},
+ relativeLineSizeDefined(false)
{
}
CharacterRun characterRun; ///< The initial character index within the whole text and the number of characters of the run.
Text::HorizontalAlignment::Type horizontalAlignment; ///< The paragraph horizontal alignment. Values "BEGIN" "CENTER" "END".
+ float relativeLineSize; ///< The relative line height to be used for this paragaraph.
bool horizontalAlignmentDefined : 1; ///< Whether the horizontal alignment is defined.
+ bool relativeLineSizeDefined : 1; ///< Whether the relative line height is defined for this paragraph.
};
} // namespace Text
glyphIndexInSecondHalfLine{0u},
characterIndexInSecondHalfLine{0u},
numberOfGlyphsInSecondHalfLine{0u},
- numberOfCharactersInSecondHalfLine{0u}
+ numberOfCharactersInSecondHalfLine{0u},
+ relativeLineSize{1.0f}
{
}
characterIndexInSecondHalfLine = 0u;
numberOfGlyphsInSecondHalfLine = 0u;
numberOfCharactersInSecondHalfLine = 0u;
+ relativeLineSize = 1.0f;
}
GlyphIndex glyphIndex; ///< Index of the first glyph to be laid-out.
CharacterIndex characterIndexInSecondHalfLine; ///< Index of the first character to be laid-out for the second half of line.
Length numberOfGlyphsInSecondHalfLine; ///< The number of glyph which fit in one line for the second half of line.
Length numberOfCharactersInSecondHalfLine; ///< The number of characters which fit in one line for the second half of line.
+
+ float relativeLineSize; ///< The relative line size to be applied for this line.
};
struct LayoutBidiParameters
* @brief get the line spacing.
*
* @param[in] textSize The text size.
+ * @param[in] relativeLineSize The relative line size to be applied.
* @return the line spacing value.
*/
- float GetLineSpacing(float textSize)
+ float GetLineSpacing(float textSize, float relativeLineSize)
{
float lineSpacing;
float relTextSize;
lineSpacing += mDefaultLineSpacing;
//subtract line spcaing if relativeLineSize < 1 & larger than min height
- relTextSize = textSize * mRelativeLineSize;
+ relTextSize = textSize * relativeLineSize;
if(relTextSize > mDefaultLineSize)
{
- if(mRelativeLineSize < 1)
+ if(relativeLineSize < 1)
{
//subtract the difference (always will be positive)
lineSpacing -= (textSize - relTextSize);
// Sets the minimum descender.
lineLayout.descender = std::min(lineLayout.descender, fontMetrics.descender);
- lineLayout.lineSpacing = GetLineSpacing(lineLayout.ascender + -lineLayout.descender);
+ lineLayout.lineSpacing = GetLineSpacing(lineLayout.ascender + -lineLayout.descender, lineLayout.relativeLineSize);
}
/**
// It needs to add as well space for the cursor if the text is in edit mode and extra space in case the text is outlined.
tmpLineLayout.penX = -glyphMetrics.xBearing + mCursorWidth + outlineWidth;
+ tmpLineLayout.relativeLineSize = lineLayout.relativeLineSize;
+
// Calculate the line height if there is no characters.
FontId lastFontId = glyphMetrics.fontId;
UpdateLineHeight(glyphMetrics, tmpLineLayout);
LineRun* lineRun = nullptr;
LineLayout ellipsisLayout;
+
+ ellipsisLayout.relativeLineSize = layout.relativeLineSize;
+
if(0u != numberOfLines)
{
// Get the last line and layout it again with the 'completelyFill' flag to true.
lineRun.direction = layout.direction;
lineRun.ellipsis = false;
- lineRun.lineSpacing = GetLineSpacing(lineRun.ascender + -lineRun.descender);
+ lineRun.lineSpacing = GetLineSpacing(lineRun.ascender + -lineRun.descender, layout.relativeLineSize);
// Update the actual size.
if(lineRun.width > layoutSize.width)
lineRun.direction = LTR;
lineRun.ellipsis = false;
- lineRun.lineSpacing = GetLineSpacing(lineRun.ascender + -lineRun.descender);
+ BoundedParagraphRun currentParagraphRun;
+ LineLayout tempLineLayout;
+ (GetBoundedParagraph(layoutParameters.textModel->GetBoundedParagraphRuns(), characterIndex, currentParagraphRun) ? SetRelativeLineSize(¤tParagraphRun, tempLineLayout) : SetRelativeLineSize(nullptr, tempLineLayout));
+
+ lineRun.lineSpacing = GetLineSpacing(lineRun.ascender + -lineRun.descender, tempLineLayout.relativeLineSize);
layoutSize.height += GetLineHeight(lineRun, true);
}
}
}
+ /**
+ * @brief Sets the relative line size for the LineLayout
+ *
+ * @param[in] currentParagraphRun Contains the bounded paragraph for this line layout.
+ * @param[in,out] lineLayout The line layout to be updated.
+ */
+ void SetRelativeLineSize(BoundedParagraphRun* currentParagraphRun, LineLayout& lineLayout)
+ {
+ lineLayout.relativeLineSize = mRelativeLineSize;
+
+ if(currentParagraphRun != nullptr && currentParagraphRun->relativeLineSizeDefined)
+ {
+ lineLayout.relativeLineSize = currentParagraphRun->relativeLineSize;
+ }
+ }
+
+ /**
+ * @brief Get the bounded paragraph for the characterIndex if exists.
+ *
+ * @param[in] boundedParagraphRuns The bounded paragraph list to search in.
+ * @param[in] characterIndex The character index to get bounded paragraph for.
+ * @param[out] currentParagraphRun Contains the bounded paragraph if found for the characterIndex.
+ *
+ * @return returns true if a bounded paragraph was found.
+ */
+ bool GetBoundedParagraph(const Vector<BoundedParagraphRun> boundedParagraphRuns, CharacterIndex characterIndex, BoundedParagraphRun& currentParagraphRun)
+ {
+ for(Vector<BoundedParagraphRun>::Iterator it = boundedParagraphRuns.Begin(),
+ endIt = boundedParagraphRuns.End();
+ it != endIt;
+ ++it)
+ {
+ BoundedParagraphRun& tempParagraphRun = *it;
+
+ if(characterIndex >= tempParagraphRun.characterRun.characterIndex &&
+ characterIndex < (tempParagraphRun.characterRun.characterIndex + tempParagraphRun.characterRun.numberOfCharacters))
+ {
+ currentParagraphRun = tempParagraphRun;
+ return true;
+ }
+ }
+
+ return false;
+ }
+
bool LayoutText(Parameters& layoutParameters,
Size& layoutSize,
bool elideTextEnabled,
layoutParameters.textModel->mVisualModel->SetFirstMiddleIndexOfElidedGlyphs(0u);
layoutParameters.textModel->mVisualModel->SetSecondMiddleIndexOfElidedGlyphs(0u);
- Vector<LineRun>& lines = layoutParameters.textModel->mVisualModel->mLines;
+ Vector<LineRun>& lines = layoutParameters.textModel->mVisualModel->mLines;
+ const Vector<BoundedParagraphRun>& boundedParagraphRuns = layoutParameters.textModel->GetBoundedParagraphRuns();
if(0u == layoutParameters.numberOfGlyphs)
{
// Retrieve BiDi info.
const bool hasBidiParagraphs = !layoutParameters.textModel->mLogicalModel->mBidirectionalParagraphInfo.Empty();
- const CharacterIndex* const glyphsToCharactersBuffer = hasBidiParagraphs ? layoutParameters.textModel->mVisualModel->mGlyphsToCharacters.Begin() : nullptr;
+ const CharacterIndex* const glyphsToCharactersBuffer = layoutParameters.textModel->mVisualModel->mGlyphsToCharacters.Begin();
const Vector<BidirectionalParagraphInfoRun>& bidirectionalParagraphsInfo = layoutParameters.textModel->mLogicalModel->mBidirectionalParagraphInfo;
const Vector<BidirectionalLineInfoRun>& bidirectionalLinesInfo = layoutParameters.textModel->mLogicalModel->mBidirectionalLineInfo;
LineLayout layout;
layout.direction = layoutBidiParameters.paragraphDirection;
layout.glyphIndex = index;
+
+ BoundedParagraphRun currentParagraphRun;
+ (GetBoundedParagraph(boundedParagraphRuns, *(glyphsToCharactersBuffer + index), currentParagraphRun) ? SetRelativeLineSize(¤tParagraphRun, layout) : SetRelativeLineSize(nullptr, layout));
+
GetLineLayoutForBox(layoutParameters,
layoutBidiParameters,
layout,
DALI_LOG_INFO(gLogFilter, Debug::Verbose, " number of characters %d\n", layout.numberOfCharacters);
DALI_LOG_INFO(gLogFilter, Debug::Verbose, " length %f\n", layout.length);
+ CharacterIndex lastCharacterInParagraph = currentParagraphRun.characterRun.characterIndex + currentParagraphRun.characterRun.numberOfCharacters - 1;
+
+ //check if this is the last line in paragraph, if false we should use the default relative line size (the one set using the property)
+ if(lastCharacterInParagraph >= layout.characterIndex && lastCharacterInParagraph < layout.characterIndex+layout.numberOfCharacters)
+ {
+ layout.relativeLineSize = mRelativeLineSize;
+ }
+
if(0u == layout.numberOfGlyphs + layout.numberOfGlyphsInSecondHalfLine)
{
// The width is too small and no characters are laid-out.
}
// Updates the vertical pen's position.
- penY += -layout.descender + layout.lineSpacing + GetLineSpacing(layout.ascender + -layout.descender);
+ penY += -layout.descender + layout.lineSpacing + GetLineSpacing(layout.ascender + -layout.descender, layout.relativeLineSize);
// Increase the glyph index.
index = nextIndex;
namespace
{
const std::string XHTML_ALIGN_ATTRIBUTE("align");
-}
+const std::string XHTML_RELATIVE_LINE_HEIGHT_ATTRIBUTE("rel-line-height");
+} // namespace
void ProcessHorizontalAlignment(const Attribute& attribute, BoundedParagraphRun& boundedParagraphRun)
{
boundedParagraphRun.horizontalAlignment);
}
+void ProcessRelativeLineHeight(const Attribute& attribute, BoundedParagraphRun& boundedParagraphRun)
+{
+ boundedParagraphRun.relativeLineSize = StringToFloat(attribute.valueBuffer);
+ boundedParagraphRun.relativeLineSizeDefined = true;
+}
+
void ProcessAttributesOfParagraphTag(const Tag& tag, BoundedParagraphRun& boundedParagraphRun)
{
// By default the align attribute is not defined until it's parsed.
{
ProcessHorizontalAlignment(attribute, boundedParagraphRun);
}
+ else if(TokenComparison(XHTML_RELATIVE_LINE_HEIGHT_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength))
+ {
+ ProcessRelativeLineHeight(attribute, boundedParagraphRun);
+ }
}
}
-
} // namespace Text
} // namespace Toolkit
*/
void ProcessAttributesOfParagraphTag(const Tag& tag, BoundedParagraphRun& boundedParagraphRun);
+/**
+ * @brief Retrieves the relative line height value from the paragraph tag and sets it to the bounded paragraph run.
+ *
+ * @param[in] attribute the relative line height attribute.
+ * @param[in,out] boundedParagraphRun The bounded paragraph run.
+ */
+void ProcessRelativeLineHeight(const Attribute& attribute, BoundedParagraphRun& boundedParagraphRun);
+
} // namespace Text
} // namespace Toolkit