/*
- * 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.
// INTERNAL INCLUDES
#include <dali-toolkit/internal/text/cursor-helper-functions.h>
-#include <dali-toolkit/internal/text/text-controller-impl-event-handler.h>
+#include <dali-toolkit/internal/text/glyph-metrics-helper.h>
+#include <dali-toolkit/internal/text/rendering/styles/character-spacing-helper-functions.h>
+#include <dali-toolkit/internal/text/controller/text-controller-impl-event-handler.h>
using namespace Dali;
}
// 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<CharacterIndex>& glyphToCharacterMap = visualModel->mGlyphsToCharacters;
+ const CharacterIndex* glyphToCharacterMapBuffer = glyphToCharacterMap.Begin();
+
+ // Get the character-spacing runs.
+ const Vector<CharacterSpacingGlyphRun>& characterSpacingGlyphRuns = visualModel->GetCharacterSpacingGlyphRuns();
// Get the lines where the glyphs are laid-out.
const LineRun* lineRun = visualModel->mLines.Begin();
lineRun += firstLineIndex;
// 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.
+ // 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;
// 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<float>(numberOfCharactersStart);
+ const float glyphAdvance = calculatedAdvance / static_cast<float>(numberOfCharactersStart);
const CharacterIndex interGlyphIndex = selectionStart - *(glyphToCharacterBuffer + glyphStart);
// Get the direction of the character.
CharacterDirection isCurrentRightToLeft = false;
{
// 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<float>(numberOfCharactersEnd);
+ const float glyphAdvance = calculatedAdvance / static_cast<float>(numberOfCharactersEnd);
const CharacterIndex interGlyphIndex = selectionEnd - *(glyphToCharacterBuffer + glyphEnd);
// Get the direction of the character.
CharacterDirection isCurrentRightToLeft = false;
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.
++lineIndex;
if(lineIndex < firstLineIndex + numberOfLines)
{
+ float currentLineSpacing = lineRun->lineSpacing;
+
// Retrieve the next line.
++lineRun;
selectionBoxInfo->maxX = MIN_FLOAT;
// Update the line's vertical offset.
- selectionBoxInfo->lineOffset = currentLineOffset + currentLineHeight;
+ selectionBoxInfo->lineOffset = currentLineOffset + currentLineHeight + currentLineSpacing;
// 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.
+ // 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;
+ }
}
}
}
if(characterHit || (Controller::NoTextTap::HIGHLIGHT == action))
{
+ uint32_t oldStart = eventData->mLeftSelectionPosition;
+ uint32_t oldEnd = eventData->mRightSelectionPosition;
+
impl.ChangeState(EventData::SELECTING);
eventData->mLeftSelectionPosition = selectionStart;
// 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)
{