From: Bowon Ryu Date: Fri, 1 Apr 2022 10:04:30 +0000 (+0000) Subject: Merge "Support paragraph attribute: relative line height" into devel/master X-Git-Tag: dali_2.1.17~7 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=66dc29e50b21f132ca11e1b274c401c243938281;hp=-c Merge "Support paragraph attribute: relative line height" into devel/master --- 66dc29e50b21f132ca11e1b274c401c243938281 diff --combined automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp index c21f9a3,fe83ae8..22dfc9f --- a/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp @@@ -20,8 -20,6 +20,8 @@@ #include #include #include + +#include #include #include #include @@@ -3632,9 -3630,6 +3632,9 @@@ int UtcDaliTextEditorEnableEditing(void application.SendNotification(); application.Render(); + textEditor.SetProperty(DevelActor::Property::USER_INTERACTION_ENABLED, true); + DALI_TEST_EQUALS(textEditor.GetProperty(DevelActor::Property::USER_INTERACTION_ENABLED).Get(), true, TEST_LOCATION); + textEditor.SetKeyInputFocus(); textEditor.SetProperty(DevelTextEditor::Property::ENABLE_EDITING, false); application.ProcessEvent(GenerateKey("D", "", "D", KEY_D_CODE, 0, 0, Integration::KeyEvent::DOWN, "D", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE)); @@@ -3657,24 -3652,6 +3657,24 @@@ DALI_TEST_EQUALS(textEditor.GetProperty(TextEditor::Property::TEXT).Get(), "D", TEST_LOCATION); DALI_TEST_EQUALS(textEditor.GetProperty(DevelTextEditor::Property::ENABLE_EDITING).Get(), true, TEST_LOCATION); + // Check the user interaction enabled and for coverage + DevelTextEditor::SelectWholeText(textEditor); + + // Render and notify + application.SendNotification(); + application.Render(); + + textEditor.SetKeyInputFocus(); + textEditor.SetProperty(DevelActor::Property::USER_INTERACTION_ENABLED, false); + application.ProcessEvent(GenerateKey("D", "", "D", KEY_D_CODE, 0, 0, Integration::KeyEvent::DOWN, "D", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE)); + + // Render and notify + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(textEditor.GetProperty(TextEditor::Property::TEXT).Get(), "D", TEST_LOCATION); + DALI_TEST_EQUALS(textEditor.GetProperty(DevelActor::Property::USER_INTERACTION_ENABLED).Get(), false, TEST_LOCATION); + END_TEST; } @@@ -5788,6 -5765,55 +5788,55 @@@ int UtcDaliToolkitTextEditorUnderlineTy 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, "

line 1

line 2

line 3

line 4

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, "

line 1

line\n2

line 3

line\n4

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; @@@ -5947,83 -5973,4 +5996,83 @@@ int UtcDaliToolkitTexteditorParagraphTa application.Render(); END_TEST; +} + +//Handle Emoji clustering for cursor handling +int utcDaliTextEditorClusteredEmojiDeletionBackSpaceKey(void) +{ + ToolkitTestApplication application; + tet_infoline(" utcDaliTextEditorClusteredEmojiDeletionBackSpaceKey "); + TextEditor textEditor = TextEditor::New(); + DALI_TEST_CHECK(textEditor); + + application.GetScene().Add(textEditor); + + // Avoid a crash when core load gl resources. + application.GetGlAbstraction().SetCheckFramebufferStatusResult(GL_FRAMEBUFFER_COMPLETE); + + textEditor.SetProperty(TextEditor::Property::TEXT, "ABC👨‍👩‍👧‍👦XY"); + textEditor.SetProperty(Dali::Toolkit::TextEditor::Property::ENABLE_MARKUP, true); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Set currsor + textEditor.SetProperty(DevelTextEditor::Property::PRIMARY_CURSOR_POSITION, 10); + application.SendNotification(); + application.Render(); + + // Set focus and remove Emoji + textEditor.SetKeyInputFocus(); + application.ProcessEvent(GenerateKey("", "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::DOWN, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE)); + + //Check the changed text and cursor position + DALI_TEST_EQUALS(textEditor.GetProperty(TextEditor::Property::TEXT).Get(), "ABCXY", TEST_LOCATION); + DALI_TEST_EQUALS(textEditor.GetProperty(DevelTextEditor::Property::PRIMARY_CURSOR_POSITION).Get(), 3, TEST_LOCATION); + + // Render and notify + application.SendNotification(); + application.Render(); + + END_TEST; +} + +int utcDaliTextEditorClusteredEmojiDeletionDeleteKey(void) +{ + ToolkitTestApplication application; + tet_infoline(" utcDaliTextEditorClusteredEmojiDeletionDeleteKey "); + TextEditor textEditor = TextEditor::New(); + DALI_TEST_CHECK(textEditor); + + application.GetScene().Add(textEditor); + + // Avoid a crash when core load gl resources. + application.GetGlAbstraction().SetCheckFramebufferStatusResult(GL_FRAMEBUFFER_COMPLETE); + + textEditor.SetProperty(TextEditor::Property::TEXT, "ABC👨‍👩‍👧‍👦XY"); + textEditor.SetProperty(Dali::Toolkit::TextEditor::Property::ENABLE_MARKUP, true); + + // Render and notify + application.SendNotification(); + application.Render(); + + // Set currsor + textEditor.SetProperty(DevelTextEditor::Property::PRIMARY_CURSOR_POSITION, 3); + application.SendNotification(); + application.Render(); + + // Set focus and remove Emoji + textEditor.SetKeyInputFocus(); + application.ProcessEvent(GenerateKey("", "", "", Dali::DevelKey::DALI_KEY_DELETE, 0, 0, Integration::KeyEvent::DOWN, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE)); + + //Check the changed text and cursor position + DALI_TEST_EQUALS(textEditor.GetProperty(TextEditor::Property::TEXT).Get(), "ABCXY", TEST_LOCATION); + DALI_TEST_EQUALS(textEditor.GetProperty(DevelTextEditor::Property::PRIMARY_CURSOR_POSITION).Get(), 3, TEST_LOCATION); + + // Render and notify + application.SendNotification(); + application.Render(); + + END_TEST; } diff --combined dali-toolkit/internal/text/layouts/layout-engine.cpp index 3fcc82c,b701086..41e41a9 --- a/dali-toolkit/internal/text/layouts/layout-engine.cpp +++ b/dali-toolkit/internal/text/layouts/layout-engine.cpp @@@ -30,7 -30,6 +30,7 @@@ #include #include #include +#include namespace Dali { @@@ -97,7 -96,8 +97,8 @@@ struct LineLayou glyphIndexInSecondHalfLine{0u}, characterIndexInSecondHalfLine{0u}, numberOfGlyphsInSecondHalfLine{0u}, - numberOfCharactersInSecondHalfLine{0u} + numberOfCharactersInSecondHalfLine{0u}, + relativeLineSize{1.0f} { } @@@ -120,6 -120,7 +121,7 @@@ characterIndexInSecondHalfLine = 0u; numberOfGlyphsInSecondHalfLine = 0u; numberOfCharactersInSecondHalfLine = 0u; + relativeLineSize = 1.0f; } GlyphIndex glyphIndex; ///< Index of the first glyph to be laid-out. @@@ -140,6 -141,8 +142,8 @@@ 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 @@@ -173,9 -176,10 +177,10 @@@ struct Engine::Imp * @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; @@@ -188,10 -192,10 +193,10 @@@ 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); @@@ -240,7 -244,7 +245,7 @@@ // 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); } /** @@@ -300,10 -304,7 +305,10 @@@ const float outlineWidth = static_cast(parameters.textModel->GetOutlineWidth()); const GlyphIndex lastGlyphOfParagraphPlusOne = parameters.startGlyphIndex + parameters.numberOfGlyphs; - const float characterSpacing = parameters.textModel->mVisualModel->GetCharacterSpacing(); + const float modelCharacterSpacing = parameters.textModel->mVisualModel->GetCharacterSpacing(); + + // Get the character-spacing runs. + const Vector& characterSpacingGlyphRuns = parameters.textModel->mVisualModel->GetCharacterSpacingGlyphRuns(); CharacterIndex characterLogicalIndex = 0u; CharacterIndex characterVisualIndex = 0u; @@@ -334,8 -335,7 +339,8 @@@ { const GlyphInfo& glyphInfo = *(glyphsBuffer + *(charactersToGlyphsBuffer + characterVisualIndex)); - calculatedAdvance = GetCalculatedAdvance(*(textBuffer + characterVisualIndex), characterSpacing, glyphInfo.advance); + const float characterSpacing = GetGlyphCharacterSpacing(characterVisualIndex, characterSpacingGlyphRuns, modelCharacterSpacing); + calculatedAdvance = GetCalculatedAdvance(*(textBuffer + characterVisualIndex), characterSpacing, glyphInfo.advance); whiteSpaceLengthEndOfLine += calculatedAdvance; ++characterLogicalIndex; @@@ -357,8 -357,7 +362,8 @@@ { const GlyphInfo& glyphInfo = *(glyphsBuffer + *(charactersToGlyphsBuffer + characterVisualIndex)); - calculatedAdvance = GetCalculatedAdvance(*(textBuffer + characterVisualIndex), characterSpacing, glyphInfo.advance); + const float characterSpacing = GetGlyphCharacterSpacing(characterVisualIndex, characterSpacingGlyphRuns, modelCharacterSpacing); + calculatedAdvance = GetCalculatedAdvance(*(textBuffer + characterVisualIndex), characterSpacing, glyphInfo.advance); whiteSpaceLengthEndOfLine += calculatedAdvance; ++characterLogicalIndex; @@@ -376,8 -375,7 +381,8 @@@ charactersPerGlyphBuffer); GlyphMetrics glyphMetrics; - calculatedAdvance = GetCalculatedAdvance(*(textBuffer + characterVisualIndex), characterSpacing, (*(glyphsBuffer + glyphIndex)).advance); + const float characterSpacing = GetGlyphCharacterSpacing(glyphIndex, characterSpacingGlyphRuns, modelCharacterSpacing); + calculatedAdvance = GetCalculatedAdvance(*(textBuffer + characterVisualIndex), characterSpacing, (*(glyphsBuffer + glyphIndex)).advance); GetGlyphsMetrics(glyphIndex, numberOfGLyphsInGroup, glyphMetrics, @@@ -408,8 -406,7 +413,8 @@@ characterLogicalIndex += *(charactersPerGlyphBuffer + glyphIndex + numberOfGLyphsInGroup - 1u); GlyphMetrics glyphMetrics; - calculatedAdvance = GetCalculatedAdvance(*(textBuffer + characterVisualIndex), characterSpacing, (*(glyphsBuffer + glyphIndex)).advance); + const float characterSpacing = GetGlyphCharacterSpacing(glyphIndex, characterSpacingGlyphRuns, modelCharacterSpacing); + calculatedAdvance = GetCalculatedAdvance(*(textBuffer + characterVisualIndex), characterSpacing, (*(glyphsBuffer + glyphIndex)).advance); GetGlyphsMetrics(glyphIndex, numberOfGLyphsInGroup, glyphMetrics, @@@ -471,8 -468,7 +476,8 @@@ characterLogicalIndex += *(charactersPerGlyphBuffer + glyphIndex + numberOfGLyphsInGroup - 1u); GlyphMetrics glyphMetrics; - calculatedAdvance = GetCalculatedAdvance(*(textBuffer + characterVisualIndex), characterSpacing, (*(glyphsBuffer + glyphIndex)).advance); + const float characterSpacing = GetGlyphCharacterSpacing(glyphIndex, characterSpacingGlyphRuns, modelCharacterSpacing); + calculatedAdvance = GetCalculatedAdvance(*(textBuffer + characterVisualIndex), characterSpacing, (*(glyphsBuffer + glyphIndex)).advance); GetGlyphsMetrics(glyphIndex, numberOfGLyphsInGroup, glyphMetrics, @@@ -709,17 -705,13 +714,17 @@@ bool isSecondHalf = false; // Character Spacing - const float characterSpacing = parameters.textModel->mVisualModel->GetCharacterSpacing(); + const float modelCharacterSpacing = parameters.textModel->mVisualModel->GetCharacterSpacing(); float calculatedAdvance = 0.f; Vector& glyphToCharacterMap = parameters.textModel->mVisualModel->mGlyphsToCharacters; const CharacterIndex* glyphToCharacterMapBuffer = glyphToCharacterMap.Begin(); + // Get the character-spacing runs. + const Vector& characterSpacingGlyphRuns = parameters.textModel->mVisualModel->GetCharacterSpacingGlyphRuns(); + GlyphMetrics glyphMetrics; - calculatedAdvance = GetCalculatedAdvance(*(textBuffer + (*(glyphToCharacterMapBuffer + lineLayout.glyphIndex))), characterSpacing, (*(glyphsBuffer + lineLayout.glyphIndex)).advance); + const float characterSpacing = GetGlyphCharacterSpacing(lineLayout.glyphIndex, characterSpacingGlyphRuns, modelCharacterSpacing); + calculatedAdvance = GetCalculatedAdvance(*(textBuffer + (*(glyphToCharacterMapBuffer + lineLayout.glyphIndex))), characterSpacing, (*(glyphsBuffer + lineLayout.glyphIndex)).advance); GetGlyphsMetrics(lineLayout.glyphIndex, numberOfGLyphsInGroup, glyphMetrics, @@@ -740,6 -732,8 +745,8 @@@ // 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); @@@ -760,8 -754,7 +767,8 @@@ charactersPerGlyphBuffer); GlyphMetrics glyphMetrics; - calculatedAdvance = GetCalculatedAdvance(*(textBuffer + (*(glyphToCharacterMapBuffer + glyphIndex))), characterSpacing, (*(glyphsBuffer + glyphIndex)).advance); + const float characterSpacing = GetGlyphCharacterSpacing(glyphIndex, characterSpacingGlyphRuns, modelCharacterSpacing); + calculatedAdvance = GetCalculatedAdvance(*(textBuffer + (*(glyphToCharacterMapBuffer + glyphIndex))), characterSpacing, (*(glyphsBuffer + glyphIndex)).advance); GetGlyphsMetrics(glyphIndex, numberOfGLyphsInGroup, glyphMetrics, @@@ -861,8 -854,7 +868,8 @@@ while(tmpLineLayout.length + tmpLineLayout.whiteSpaceLengthEndOfLine > targetWidth && glyphIndexToRemove < glyphIndex) { GlyphMetrics glyphMetrics; - calculatedAdvance = GetCalculatedAdvance(*(textBuffer + (*(glyphToCharacterMapBuffer + glyphIndexToRemove))), characterSpacing, (*(glyphsBuffer + glyphIndexToRemove)).advance); + const float characterSpacing = GetGlyphCharacterSpacing(glyphIndexToRemove, characterSpacingGlyphRuns, modelCharacterSpacing); + calculatedAdvance = GetCalculatedAdvance(*(textBuffer + (*(glyphToCharacterMapBuffer + glyphIndexToRemove))), characterSpacing, (*(glyphsBuffer + glyphIndexToRemove)).advance); GetGlyphsMetrics(glyphIndexToRemove, numberOfGLyphsInGroup, glyphMetrics, @@@ -1268,6 -1260,9 +1275,9 @@@ 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. @@@ -1424,7 -1419,7 +1434,7 @@@ 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) @@@ -1478,7 -1473,11 +1488,11 @@@ 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); } @@@ -1538,6 -1537,51 +1552,51 @@@ } } + /** + * @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 boundedParagraphRuns, CharacterIndex characterIndex, BoundedParagraphRun& currentParagraphRun) + { + for(Vector::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, @@@ -1556,7 -1600,8 +1615,8 @@@ layoutParameters.textModel->mVisualModel->SetFirstMiddleIndexOfElidedGlyphs(0u); layoutParameters.textModel->mVisualModel->SetSecondMiddleIndexOfElidedGlyphs(0u); - Vector& lines = layoutParameters.textModel->mVisualModel->mLines; + Vector& lines = layoutParameters.textModel->mVisualModel->mLines; + const Vector& boundedParagraphRuns = layoutParameters.textModel->GetBoundedParagraphRuns(); if(0u == layoutParameters.numberOfGlyphs) { @@@ -1616,7 -1661,7 +1676,7 @@@ // 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& bidirectionalParagraphsInfo = layoutParameters.textModel->mLogicalModel->mBidirectionalParagraphInfo; const Vector& bidirectionalLinesInfo = layoutParameters.textModel->mLogicalModel->mBidirectionalLineInfo; @@@ -1720,6 -1765,10 +1780,10 @@@ 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, @@@ -1734,6 -1783,14 +1798,14 @@@ 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. @@@ -1877,7 -1934,7 +1949,7 @@@ } // 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;