X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ftext%2Ftext-selection-handle-controller.cpp;h=fef3baa5938baca0bb61885bcec8c8a4e510ce5e;hp=b0825108fb7942309d37873eaad3b2056b2385ce;hb=020b07151378db83ab8e12eb3e2d51db0ed69996;hpb=b13abf6bf040c3af7b683c9d326d304bdb5f52cc diff --git a/dali-toolkit/internal/text/text-selection-handle-controller.cpp b/dali-toolkit/internal/text/text-selection-handle-controller.cpp index b082510..fef3baa 100644 --- a/dali-toolkit/internal/text/text-selection-handle-controller.cpp +++ b/dali-toolkit/internal/text/text-selection-handle-controller.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,7 +23,9 @@ // INTERNAL INCLUDES #include -#include +#include +#include +#include using namespace Dali; @@ -103,10 +105,16 @@ void SelectionHandleController::Reposition(Controller::Impl& impl) } // Get the indices to the first and last selected glyphs. - const CharacterIndex selectionEndMinusOne = selectionEnd - 1u; - const GlyphIndex glyphStart = *(charactersToGlyphBuffer + selectionStart); - const Length numberOfGlyphs = *(glyphsPerCharacterBuffer + selectionEndMinusOne); - const GlyphIndex glyphEnd = *(charactersToGlyphBuffer + selectionEndMinusOne) + ((numberOfGlyphs > 0) ? numberOfGlyphs - 1u : 0u); + const CharacterIndex selectionEndMinusOne = selectionEnd - 1u; + const GlyphIndex glyphStart = *(charactersToGlyphBuffer + selectionStart); + const Length numberOfGlyphs = *(glyphsPerCharacterBuffer + selectionEndMinusOne); + const GlyphIndex glyphEnd = *(charactersToGlyphBuffer + selectionEndMinusOne) + ((numberOfGlyphs > 0) ? numberOfGlyphs - 1u : 0u); + const float modelCharacterSpacing = visualModel->GetCharacterSpacing(); + Vector& glyphToCharacterMap = visualModel->mGlyphsToCharacters; + const CharacterIndex* glyphToCharacterMapBuffer = glyphToCharacterMap.Begin(); + + // Get the character-spacing runs. + const Vector& characterSpacingGlyphRuns = visualModel->GetCharacterSpacingGlyphRuns(); // Get the lines where the glyphs are laid-out. const LineRun* lineRun = visualModel->mLines.Begin(); @@ -144,7 +152,9 @@ void SelectionHandleController::Reposition(Controller::Impl& impl) lineRun += firstLineIndex; - selectionBoxInfo->lineHeight = GetLineHeight(*lineRun); + // The line height is the addition of the line ascender and the line descender. + // However, the line descender has a negative value, hence the subtraction also line spacing should not be included in selection height. + selectionBoxInfo->lineHeight = lineRun->ascender - lineRun->descender; GlyphIndex lastGlyphOfLine = lineRun->glyphRun.glyphIndex + lineRun->glyphRun.numberOfGlyphs - 1u; @@ -163,18 +173,21 @@ void SelectionHandleController::Reposition(Controller::Impl& impl) // Count the actual number of quads. unsigned int actualNumberOfQuads = 0u; Vector4 quad; + float calculatedAdvance = 0.f; // Traverse the glyphs. for(GlyphIndex index = glyphStart; index <= glyphEnd; ++index) { - const GlyphInfo& glyph = *(glyphsBuffer + index); - const Vector2& position = *(positionsBuffer + index); + const float characterSpacing = GetGlyphCharacterSpacing(index, characterSpacingGlyphRuns, modelCharacterSpacing); + const GlyphInfo& glyph = *(glyphsBuffer + index); + const Vector2& position = *(positionsBuffer + index); + calculatedAdvance = GetCalculatedAdvance(*(logicalModel->mText.Begin() + (*(glyphToCharacterMapBuffer + index))), characterSpacing, glyph.advance); if(splitStartGlyph) { // If the first glyph is a ligature that must be broken it may be needed to add only part of the glyph to the highlight box. - const float glyphAdvance = glyph.advance / static_cast(numberOfCharactersStart); + const float glyphAdvance = calculatedAdvance / static_cast(numberOfCharactersStart); const CharacterIndex interGlyphIndex = selectionStart - *(glyphToCharacterBuffer + glyphStart); // Get the direction of the character. CharacterDirection isCurrentRightToLeft = false; @@ -207,7 +220,7 @@ void SelectionHandleController::Reposition(Controller::Impl& impl) { // Equally, if the last glyph is a ligature that must be broken it may be needed to add only part of the glyph to the highlight box. - const float glyphAdvance = glyph.advance / static_cast(numberOfCharactersEnd); + const float glyphAdvance = calculatedAdvance / static_cast(numberOfCharactersEnd); const CharacterIndex interGlyphIndex = selectionEnd - *(glyphToCharacterBuffer + glyphEnd); // Get the direction of the character. CharacterDirection isCurrentRightToLeft = false; @@ -237,7 +250,7 @@ void SelectionHandleController::Reposition(Controller::Impl& impl) quad.x = lineRun->alignmentOffset + position.x - glyph.xBearing + model->mScrollPosition.x; quad.y = selectionBoxInfo->lineOffset; - quad.z = quad.x + glyph.advance; + quad.z = quad.x + calculatedAdvance; quad.w = quad.y + selectionBoxInfo->lineHeight; // Store the min and max 'x' for each line. @@ -254,6 +267,8 @@ void SelectionHandleController::Reposition(Controller::Impl& impl) ++lineIndex; if(lineIndex < firstLineIndex + numberOfLines) { + float currentLineSpacing = lineRun->lineSpacing; + // Retrieve the next line. ++lineRun; @@ -271,9 +286,16 @@ void SelectionHandleController::Reposition(Controller::Impl& impl) selectionBoxInfo->maxX = MIN_FLOAT; // Update the line's vertical offset. - selectionBoxInfo->lineOffset = currentLineOffset + currentLineHeight; + selectionBoxInfo->lineOffset = currentLineOffset + currentLineHeight + currentLineSpacing; - selectionBoxInfo->lineHeight = GetLineHeight(*lineRun); + // The line height is the addition of the line ascender and the line descender. + // However, the line descender has a negative value, hence the subtraction also line spacing should not be included in selection height. + selectionBoxInfo->lineHeight = lineRun->ascender - lineRun->descender; + + if(lineRun->lineSpacing > 0) + { + selectionBoxInfo->lineHeight += lineRun->lineSpacing; + } } } } @@ -491,6 +513,9 @@ void SelectionHandleController::Reposition(Controller::Impl& impl, float visualX if(characterHit || (Controller::NoTextTap::HIGHLIGHT == action)) { + uint32_t oldStart = eventData->mLeftSelectionPosition; + uint32_t oldEnd = eventData->mRightSelectionPosition; + impl.ChangeState(EventData::SELECTING); eventData->mLeftSelectionPosition = selectionStart; @@ -510,6 +535,11 @@ void SelectionHandleController::Reposition(Controller::Impl& impl, float visualX // Cursor to be positioned at end of selection so if selection interrupted and edit mode restarted the cursor will be at end of selection eventData->mPrimaryCursorPosition = std::max(eventData->mLeftSelectionPosition, eventData->mRightSelectionPosition); + + if(impl.mSelectableControlInterface != nullptr) + { + impl.mSelectableControlInterface->SelectionChanged(oldStart, oldEnd, eventData->mLeftSelectionPosition, eventData->mRightSelectionPosition); + } } else if(Controller::NoTextTap::SHOW_SELECTION_POPUP == action) {