X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ftext%2Ftext-view.cpp;h=0be5ac608fc99f301b0e07fe08e345cbd9320b97;hb=refs%2Fchanges%2F95%2F275895%2F6;hp=f8a2722ac988c2de712214325d5059907deafcb7;hpb=2d59f0b716ea7f7c06de0732d3e4e78aea127de6;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git diff --git a/dali-toolkit/internal/text/text-view.cpp b/dali-toolkit/internal/text/text-view.cpp index f8a2722..0be5ac6 100644 --- a/dali-toolkit/internal/text/text-view.cpp +++ b/dali-toolkit/internal/text/text-view.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -23,6 +23,10 @@ #include #include +// INTERNAL INCLUDES +#include +#include + namespace Dali { namespace Toolkit @@ -32,6 +36,7 @@ namespace Text struct View::Impl { VisualModelPtr mVisualModel; + LogicalModelPtr mLogicalModel; TextAbstraction::FontClient mFontClient; ///< Handle to the font client. }; @@ -53,6 +58,11 @@ void View::SetVisualModel(VisualModelPtr visualModel) mImpl->mVisualModel = visualModel; } +void View::SetLogicalModel(LogicalModelPtr logicalModel) +{ + mImpl->mLogicalModel = logicalModel; +} + const Vector2& View::GetControlSize() const { if(mImpl->mVisualModel) @@ -96,17 +106,25 @@ Length View::GetGlyphs(GlyphInfo* glyphs, GlyphIndex glyphIndex, Length numberOfGlyphs) const { - Length numberOfLaidOutGlyphs = 0u; - Length numberOfActualLaidOutGlyphs = 0u; + Length numberOfLaidOutGlyphs = 0u; + Length numberOfActualLaidOutGlyphs = 0u; + const float modelCharacterSpacing = mImpl->mVisualModel->GetCharacterSpacing(); + Vector& glyphToCharacterMap = mImpl->mVisualModel->mGlyphsToCharacters; + const CharacterIndex* glyphToCharacterMapBuffer = glyphToCharacterMap.Begin(); + float calculatedAdvance = 0.f; + const Character* textBuffer = mImpl->mLogicalModel->mText.Begin(); if(mImpl->mVisualModel) { + // Get the character-spacing runs. + const Vector& characterSpacingGlyphRuns = mImpl->mVisualModel->GetCharacterSpacingGlyphRuns(); + bool textElided = false; DevelText::EllipsisPosition::Type ellipsisPosition = GetEllipsisPosition(); //Reset indices of ElidedGlyphs mImpl->mVisualModel->SetStartIndexOfElidedGlyphs(0u); - mImpl->mVisualModel->SetEndIndexOfElidedGlyphs(numberOfGlyphs); + mImpl->mVisualModel->SetEndIndexOfElidedGlyphs(numberOfGlyphs - 1u); // Initialization is the last index of Glyphs mImpl->mVisualModel->SetFirstMiddleIndexOfElidedGlyphs(0u); mImpl->mVisualModel->SetSecondMiddleIndexOfElidedGlyphs(0u); @@ -213,7 +231,7 @@ Length View::GetGlyphs(GlyphInfo* glyphs, if(lastGlyphIndexOfLine == index) { - penY += -line->descender; + penY += -line->descender + line->lineSpacing; // Get the next line. ++lineIndex; @@ -265,7 +283,7 @@ Length View::GetGlyphs(GlyphInfo* glyphs, const LineRun& elidedLine = *ellipsisLine; if((1u == numberOfLines) && - (elidedLine.ascender - elidedLine.descender > mImpl->mVisualModel->mControlSize.height)) + (GetLineHeight(elidedLine, true) > mImpl->mVisualModel->mControlSize.height)) { // Replace the first glyph with ellipsis glyph auto indexOfFirstGlyph = (ellipsisPosition == DevelText::EllipsisPosition::START) ? startIndexOfEllipsis : 0u; @@ -342,7 +360,9 @@ Length View::GetGlyphs(GlyphInfo* glyphs, firstPenSet = true; } - removedGlypsWidth += std::min(glyphToRemove.advance, (glyphToRemove.xBearing + glyphToRemove.width)); + const float characterSpacing = GetGlyphCharacterSpacing(indexOfEllipsis, characterSpacingGlyphRuns, modelCharacterSpacing); + calculatedAdvance = GetCalculatedAdvance(*(textBuffer + (*(glyphToCharacterMapBuffer + indexOfEllipsis))), characterSpacing, glyphToRemove.advance); + removedGlypsWidth += std::min(calculatedAdvance, (glyphToRemove.xBearing + glyphToRemove.width)); // Calculate the width of the ellipsis glyph and check if it fits. const float ellipsisGlyphWidth = ellipsisGlyph.width + ellipsisGlyph.xBearing; @@ -356,10 +376,73 @@ Length View::GetGlyphs(GlyphInfo* glyphs, glyphInfo = ellipsisGlyph; // Change the 'x' and 'y' position of the ellipsis glyph. - if(position.x > firstPenX) { - position.x = firstPenX + removedGlypsWidth - ellipsisGlyphWidth; + if(isTailMode) + { + // To handle case of the mixed languages (LTR then RTL) with + // EllipsisPosition::END and the LayoutDirection::RIGHT_TO_LEFT + float nextXPositions = ellipsisLine->width; + if(indexOfEllipsis + 1u < numberOfGlyphs) + { + Vector2& positionOfNextGlyph = *(glyphPositions + indexOfEllipsis + 1u); + nextXPositions = positionOfNextGlyph.x; + } + + if(position.x > nextXPositions) // RTL language + { + if((indexOfEllipsis > 0u) && ((position.x - nextXPositions) > removedGlypsWidth)) + { + // To handle mixed directions + // Re-calculates the first penX which will be used if rtl text is elided. + firstPenX = position.x - glyphToRemove.xBearing; + if(firstPenX < -ellipsisGlyph.xBearing) + { + // Avoids to exceed the bounding box when rtl text is elided. + firstPenX = -ellipsisGlyph.xBearing; + } + //Reset the width of removed glyphs + removedGlypsWidth = std::min(calculatedAdvance, (glyphToRemove.xBearing + glyphToRemove.width)) - ellipsisGlyph.xBearing; + + --indexOfEllipsis; + continue; + } + else + { + // To handle the case of RTL language with EllipsisPosition::END + position.x = firstPenX + removedGlypsWidth - ellipsisGlyphWidth; + } + } + } + else + { + // To handle the case of LTR language with EllipsisPosition::START + position.x = firstPenX + removedGlypsWidth - ellipsisGlyphWidth; + } + } + else + { + if(!isTailMode) + { + // To handle case of the mixed languages (RTL then LTR) with + // EllipsisPosition::START and the LayoutDirection::RIGHT_TO_LEFT + float nextXPositions = ellipsisLine->width; + if(indexOfEllipsis + 1u < numberOfGlyphs) + { + Vector2& positionOfNextGlyph = *(glyphPositions + indexOfEllipsis + 1u); + nextXPositions = positionOfNextGlyph.x; + } + + if(position.x < nextXPositions) // LTR language + { + position.x = firstPenX + removedGlypsWidth - ellipsisGlyphWidth; + + if((position.x + ellipsisGlyphWidth + ellipsisGlyph.xBearing) > nextXPositions) + { + position.x -= (position.x + ellipsisGlyphWidth + ellipsisGlyph.xBearing) - nextXPositions; + } + } + } } position.x += ellipsisGlyph.xBearing; @@ -625,6 +708,36 @@ float View::GetUnderlineHeight() const return 0.0f; } +Text::Underline::Type View::GetUnderlineType() const +{ + Text::Underline::Type type = Text::Underline::Type::SOLID; + if(mImpl->mVisualModel) + { + type = mImpl->mVisualModel->GetUnderlineType(); + } + return type; +} + +float View::GetDashedUnderlineWidth() const +{ + float width = 0.0f; + if(mImpl->mVisualModel) + { + width = mImpl->mVisualModel->GetDashedUnderlineWidth(); + } + return width; +} + +float View::GetDashedUnderlineGap() const +{ + float gap = 0.0f; + if(mImpl->mVisualModel) + { + gap = mImpl->mVisualModel->GetDashedUnderlineGap(); + } + return gap; +} + Length View::GetNumberOfUnderlineRuns() const { if(mImpl->mVisualModel) @@ -635,9 +748,9 @@ Length View::GetNumberOfUnderlineRuns() const return 0u; } -void View::GetUnderlineRuns(GlyphRun* underlineRuns, - UnderlineRunIndex index, - Length numberOfRuns) const +void View::GetUnderlineRuns(UnderlinedGlyphRun* underlineRuns, + UnderlineRunIndex index, + Length numberOfRuns) const { if(mImpl->mVisualModel) { @@ -742,6 +855,83 @@ GlyphIndex View::GetSecondMiddleIndexOfElidedGlyphs() const return secondMiddleIndexOfElidedGlyphs; } +const Vector4& View::GetStrikethroughColor() const +{ + return (mImpl->mVisualModel) ? mImpl->mVisualModel->GetStrikethroughColor() : Vector4::ZERO; +} + +bool View::IsStrikethroughEnabled() const +{ + return (mImpl->mVisualModel) ? mImpl->mVisualModel->IsStrikethroughEnabled() : false; +} + +float View::GetStrikethroughHeight() const +{ + return (mImpl->mVisualModel) ? mImpl->mVisualModel->GetStrikethroughHeight() : 0.0f; +} + +Length View::GetNumberOfStrikethroughRuns() const +{ + if(mImpl->mVisualModel) + { + return mImpl->mVisualModel->GetNumberOfStrikethroughRuns(); + } + + return 0u; +} + +void View::GetStrikethroughRuns(StrikethroughGlyphRun* strikethroughRuns, + StrikethroughRunIndex index, + Length numberOfRuns) const +{ + if(mImpl->mVisualModel) + { + mImpl->mVisualModel->GetStrikethroughRuns(strikethroughRuns, + index, + numberOfRuns); + } +} + +Length View::GetNumberOfBoundedParagraphRuns() const +{ + if(mImpl->mLogicalModel) + { + return mImpl->mLogicalModel->GetNumberOfBoundedParagraphRuns(); + } + + return 0u; +} + +const Vector& View::GetBoundedParagraphRuns() const +{ + return mImpl->mLogicalModel->GetBoundedParagraphRuns(); +} + +Length View::GetNumberOfCharacterSpacingGlyphRuns() const +{ + return (mImpl->mVisualModel) ? mImpl->mVisualModel->GetNumberOfCharacterSpacingGlyphRuns() : 0u; +} + +const Vector& View::GetCharacterSpacingGlyphRuns() const +{ + return (mImpl->mVisualModel) ? mImpl->mVisualModel->GetCharacterSpacingGlyphRuns() : GetEmptyCharacterSpacingGlyphRuns(); +} + +const float View::GetCharacterSpacing() const +{ + return (mImpl->mVisualModel) ? mImpl->mVisualModel->GetCharacterSpacing() : 0.f; +} + +const Character* View::GetTextBuffer() const +{ + return (mImpl->mVisualModel) ? mImpl->mLogicalModel->mText.Begin() : nullptr; +} + +const Vector& View::GetGlyphsToCharacters() const +{ + return mImpl->mVisualModel->GetGlyphsToCharacters(); +} + } // namespace Text } // namespace Toolkit