From: Victor Cebollada Date: Mon, 25 Jul 2016 09:33:41 +0000 (+0100) Subject: Fix text's highlight box. X-Git-Tag: dali_1.2.0~8^2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=b2d83201fba837ae079d0f608517884def2c43c7 Fix text's highlight box. * Fixed a bug when calculating the size of the highlight box. It caused the highlight box to be culled. * Replaces the std::vector by a Dali::Vector and resizes it with the number of quads to avoid reallocations. Change-Id: Ia3c027c601de9c8c23693a6786fcfdfee57edaeb Signed-off-by: Victor Cebollada --- diff --git a/dali-toolkit/internal/text/decorator/text-decorator.cpp b/dali-toolkit/internal/text/decorator/text-decorator.cpp index 58ccff6..da49940 100644 --- a/dali-toolkit/internal/text/decorator/text-decorator.cpp +++ b/dali-toolkit/internal/text/decorator/text-decorator.cpp @@ -104,36 +104,7 @@ const float CURSOR_WIDTH = 1.f; ///< The cursor's width in pixels. const float POPUP_PADDING = 2.f; ///< Padding space between the highlight box and the text's popup. -/** - * structure to hold coordinates of each quad, which will make up the mesh. - */ -struct QuadCoordinates -{ - /** - * Default constructor - */ - QuadCoordinates() - { - } - - /** - * Constructor - * @param[in] x1 left co-ordinate - * @param[in] y1 top co-ordinate - * @param[in] x2 right co-ordinate - * @param[in] y2 bottom co-ordinate - */ - QuadCoordinates(float x1, float y1, float x2, float y2) - : min(x1, y1), - max(x2, y2) - { - } - - Dali::Vector2 min; ///< top-left (minimum) position of quad - Dali::Vector2 max; ///< bottom-right (maximum) position of quad -}; - -typedef std::vector QuadContainer; +typedef Dali::Vector QuadContainer; /** * @brief Takes a bounding rectangle in the local coordinates of an actor and returns the world coordinates Bounding Box. @@ -1193,7 +1164,7 @@ struct Decorator::Impl : public ConnectionTracker mHighlightActor.SetPosition( mHighlightPosition.x, mHighlightPosition.y ); - const unsigned int numberOfQuads = mHighlightQuadList.size(); + const unsigned int numberOfQuads = mHighlightQuadList.Count(); if( 0u != numberOfQuads ) { // Set the size of the highlighted text to the actor. @@ -1213,33 +1184,33 @@ struct Decorator::Impl : public ConnectionTracker unsigned int v = 0u; // Traverse all quads. - for( std::vector::iterator it = mHighlightQuadList.begin(), - endIt = mHighlightQuadList.end(); + for( Vector::ConstIterator it = mHighlightQuadList.Begin(), + endIt = mHighlightQuadList.End(); it != endIt; ++it, v += 4u ) { - QuadCoordinates& quad = *it; + const Vector4& quad = *it; Vector2 vertex; // top-left (v+0) - vertex.x = quad.min.x - offsetX; - vertex.y = quad.min.y - offsetY; + vertex.x = quad.x - offsetX; + vertex.y = quad.y - offsetY; vertices.PushBack( vertex ); // top-right (v+1) - vertex.x = quad.max.x - offsetX; - vertex.y = quad.min.y - offsetY; + vertex.x = quad.z - offsetX; + vertex.y = quad.y - offsetY; vertices.PushBack( vertex ); // bottom-left (v+2) - vertex.x = quad.min.x - offsetX; - vertex.y = quad.max.y - offsetY; + vertex.x = quad.x - offsetX; + vertex.y = quad.w - offsetY; vertices.PushBack( vertex ); // bottom-right (v+3) - vertex.x = quad.max.x - offsetX; - vertex.y = quad.max.y - offsetY; + vertex.x = quad.z - offsetX; + vertex.y = quad.w - offsetY; vertices.PushBack( vertex ); // triangle A (3, 1, 0) @@ -1274,7 +1245,7 @@ struct Decorator::Impl : public ConnectionTracker } } - mHighlightQuadList.clear(); + mHighlightQuadList.Clear(); if( mHighlightRenderer ) { @@ -1932,7 +1903,7 @@ struct Decorator::Impl : public ConnectionTracker PropertyBuffer mQuadVertices; Geometry mQuadGeometry; - QuadContainer mHighlightQuadList; ///< Sub-selections that combine to create the complete selection highlight + QuadContainer mHighlightQuadList; ///< Sub-selections that combine to create the complete selection highlight. Vector4 mBoundingBox; ///< The bounding box in world coords. Vector4 mHighlightColor; ///< Color of the highlight @@ -2209,9 +2180,9 @@ void Decorator::SetSelectionHandleFlipState( bool indicesSwapped, bool left, boo mImpl->mFlipRightSelectionHandleDirection = right; } -void Decorator::AddHighlight( float x1, float y1, float x2, float y2 ) +void Decorator::AddHighlight( unsigned int index, const Vector4& quad ) { - mImpl->mHighlightQuadList.push_back( QuadCoordinates(x1, y1, x2, y2) ); + *( mImpl->mHighlightQuadList.Begin() + index ) = quad; } void Decorator::SetHighLightBox( const Vector2& position, const Size& size ) @@ -2222,10 +2193,15 @@ void Decorator::SetHighLightBox( const Vector2& position, const Size& size ) void Decorator::ClearHighlights() { - mImpl->mHighlightQuadList.clear(); + mImpl->mHighlightQuadList.Clear(); mImpl->mHighlightPosition = Vector2::ZERO; } +void Decorator::ResizeHighlightQuads( unsigned int numberOfQuads ) +{ + mImpl->mHighlightQuadList.Resize( numberOfQuads ); +} + void Decorator::SetHighlightColor( const Vector4& color ) { mImpl->mHighlightColor = color; diff --git a/dali-toolkit/internal/text/decorator/text-decorator.h b/dali-toolkit/internal/text/decorator/text-decorator.h index 83388f4..6e7c727 100644 --- a/dali-toolkit/internal/text/decorator/text-decorator.h +++ b/dali-toolkit/internal/text/decorator/text-decorator.h @@ -437,12 +437,10 @@ public: /** * @brief Adds a quad to the existing selection highlights. Vertices are in decorator's coordinates. * - * @param[in] x1 The top-left x position. - * @param[in] y1 The top-left y position. - * @param[in] x2 The bottom-right x position. - * @param[in] y3 The bottom-right y position. + * @param[in] index Position in the vector where to add the quad. + * @param[in] quad The quad. The 'x' and 'y' coordinates store the min 'x' and min 'y'. The 'z' and 'w' coordinates store the max 'x' and max 'y'. */ - void AddHighlight( float x1, float y1, float x2, float y2 ); + void AddHighlight( unsigned int index, const Vector4& quad ); /** * @brief Sets the min 'x,y' coordinates and the size of the highlighted box. @@ -462,6 +460,13 @@ public: void ClearHighlights(); /** + * @brief Reserves space for the highlight quads. + * + * @param[in] numberOfQuads The expected number of quads. + */ + void ResizeHighlightQuads( unsigned int numberOfQuads ); + + /** * @brief Sets the selection highlight color. * * @param[in] color The color to use. diff --git a/dali-toolkit/internal/text/text-controller-impl.cpp b/dali-toolkit/internal/text/text-controller-impl.cpp index 9637245..95115da 100644 --- a/dali-toolkit/internal/text/text-controller-impl.cpp +++ b/dali-toolkit/internal/text/text-controller-impl.cpp @@ -1788,6 +1788,14 @@ void Controller::Impl::RepositionSelectionHandles() const Length numberOfCharactersEnd = *( charactersPerGlyphBuffer + glyphEnd ); bool splitEndGlyph = ( glyphStart != glyphEnd ) && ( numberOfCharactersEnd > 1u ) && HasLigatureMustBreak( mLogicalModel->GetScript( selectionEndMinusOne ) ); + // The number of quads of the selection box. + const unsigned int numberOfQuads = 1u + ( glyphEnd - glyphStart ) + ( ( numberOfLines > 1u ) ? 2u * numberOfLines : 0u ); + mEventData->mDecorator->ResizeHighlightQuads( numberOfQuads ); + + // Count the actual number of quads. + unsigned int actualNumberOfQuads = 0u; + Vector4 quad; + // Traverse the glyphs. for( GlyphIndex index = glyphStart; index <= glyphEnd; ++index ) { @@ -1811,18 +1819,17 @@ void Controller::Impl::RepositionSelectionHandles() // Calculate the number of characters selected. const Length numberOfCharacters = ( glyphStart == glyphEnd ) ? ( selectionEnd - selectionStart ) : ( numberOfCharactersStart - interGlyphIndex ); - const float xPosition = lineRun->alignmentOffset + position.x - glyph.xBearing + mScrollPosition.x + glyphAdvance * static_cast( isCurrentRightToLeft ? ( numberOfCharactersStart - interGlyphIndex - numberOfCharacters ) : interGlyphIndex ); - const float xPositionAdvance = xPosition + static_cast( numberOfCharacters ) * glyphAdvance; - const float yPosition = selectionBoxInfo->lineOffset; + quad.x = lineRun->alignmentOffset + position.x - glyph.xBearing + mScrollPosition.x + glyphAdvance * static_cast( isCurrentRightToLeft ? ( numberOfCharactersStart - interGlyphIndex - numberOfCharacters ) : interGlyphIndex ); + quad.y = selectionBoxInfo->lineOffset; + quad.z = quad.x + static_cast( numberOfCharacters ) * glyphAdvance; + quad.w = selectionBoxInfo->lineOffset + selectionBoxInfo->lineHeight; // Store the min and max 'x' for each line. - selectionBoxInfo->minX = std::min( selectionBoxInfo->minX, xPosition ); - selectionBoxInfo->maxX = std::max( selectionBoxInfo->maxX, xPositionAdvance ); + selectionBoxInfo->minX = std::min( selectionBoxInfo->minX, quad.x ); + selectionBoxInfo->maxX = std::max( selectionBoxInfo->maxX, quad.z ); - mEventData->mDecorator->AddHighlight( xPosition, - yPosition, - xPositionAdvance, - yPosition + selectionBoxInfo->lineHeight ); + mEventData->mDecorator->AddHighlight( actualNumberOfQuads, quad ); + ++actualNumberOfQuads; splitStartGlyph = false; continue; @@ -1843,35 +1850,35 @@ void Controller::Impl::RepositionSelectionHandles() const Length numberOfCharacters = numberOfCharactersEnd - interGlyphIndex; - const float xPosition = lineRun->alignmentOffset + position.x - glyph.xBearing + mScrollPosition.x + ( isCurrentRightToLeft ? ( glyphAdvance * static_cast( numberOfCharacters ) ) : 0.f ); - const float xPositionAdvance = xPosition + static_cast( interGlyphIndex ) * glyphAdvance; - const float yPosition = selectionBoxInfo->lineOffset; + quad.x = lineRun->alignmentOffset + position.x - glyph.xBearing + mScrollPosition.x + ( isCurrentRightToLeft ? ( glyphAdvance * static_cast( numberOfCharacters ) ) : 0.f ); + quad.y = selectionBoxInfo->lineOffset; + quad.z = quad.x + static_cast( interGlyphIndex ) * glyphAdvance; + quad.w = quad.y + selectionBoxInfo->lineHeight; // Store the min and max 'x' for each line. - selectionBoxInfo->minX = std::min( selectionBoxInfo->minX, xPosition ); - selectionBoxInfo->maxX = std::max( selectionBoxInfo->maxX, xPositionAdvance ); + selectionBoxInfo->minX = std::min( selectionBoxInfo->minX, quad.x ); + selectionBoxInfo->maxX = std::max( selectionBoxInfo->maxX, quad.z ); - mEventData->mDecorator->AddHighlight( xPosition, - yPosition, - xPositionAdvance, - yPosition + selectionBoxInfo->lineHeight ); + mEventData->mDecorator->AddHighlight( actualNumberOfQuads, + quad ); + ++actualNumberOfQuads; splitEndGlyph = false; continue; } - const float xPosition = lineRun->alignmentOffset + position.x - glyph.xBearing + mScrollPosition.x; - const float xPositionAdvance = xPosition + glyph.advance; - const float yPosition = selectionBoxInfo->lineOffset; + quad.x = lineRun->alignmentOffset + position.x - glyph.xBearing + mScrollPosition.x; + quad.y = selectionBoxInfo->lineOffset; + quad.z = quad.x + glyph.advance; + quad.w = quad.y + selectionBoxInfo->lineHeight; // Store the min and max 'x' for each line. - selectionBoxInfo->minX = std::min( selectionBoxInfo->minX, xPosition ); - selectionBoxInfo->maxX = std::max( selectionBoxInfo->maxX, xPositionAdvance ); + selectionBoxInfo->minX = std::min( selectionBoxInfo->minX, quad.x ); + selectionBoxInfo->maxX = std::max( selectionBoxInfo->maxX, quad.z ); - mEventData->mDecorator->AddHighlight( xPosition, - yPosition, - xPositionAdvance, - yPosition + selectionBoxInfo->lineHeight ); + mEventData->mDecorator->AddHighlight( actualNumberOfQuads, + quad ); + ++actualNumberOfQuads; // Whether to retrieve the next line. if( index == lastGlyphOfLine ) @@ -1915,7 +1922,7 @@ void Controller::Impl::RepositionSelectionHandles() const SelectionBoxInfo& info = *it; // Update the size of the highlighted text. - highLightSize.height += selectionBoxInfo->lineHeight; + highLightSize.height += info.lineHeight; minHighlightX = std::min( minHighlightX, info.minX ); maxHighlightX = std::max( maxHighlightX, info.maxX ); } @@ -1933,11 +1940,15 @@ void Controller::Impl::RepositionSelectionHandles() if( boxifyBegin ) { + quad.x = 0.f; + quad.y = firstSelectionBoxLineInfo.lineOffset; + quad.z = firstSelectionBoxLineInfo.minX; + quad.w = firstSelectionBoxLineInfo.lineOffset + firstSelectionBoxLineInfo.lineHeight; + // Boxify at the beginning of the line. - mEventData->mDecorator->AddHighlight( 0.f, - firstSelectionBoxLineInfo.lineOffset, - firstSelectionBoxLineInfo.minX, - firstSelectionBoxLineInfo.lineOffset + firstSelectionBoxLineInfo.lineHeight ); + mEventData->mDecorator->AddHighlight( actualNumberOfQuads, + quad ); + ++actualNumberOfQuads; // Update the size of the highlighted text. minHighlightX = 0.f; @@ -1945,11 +1956,15 @@ void Controller::Impl::RepositionSelectionHandles() if( boxifyEnd ) { + quad.x = firstSelectionBoxLineInfo.maxX; + quad.y = firstSelectionBoxLineInfo.lineOffset; + quad.z = mVisualModel->mControlSize.width; + quad.w = firstSelectionBoxLineInfo.lineOffset + firstSelectionBoxLineInfo.lineHeight; + // Boxify at the end of the line. - mEventData->mDecorator->AddHighlight( firstSelectionBoxLineInfo.maxX, - firstSelectionBoxLineInfo.lineOffset, - mVisualModel->mControlSize.width, - firstSelectionBoxLineInfo.lineOffset + firstSelectionBoxLineInfo.lineHeight ); + mEventData->mDecorator->AddHighlight( actualNumberOfQuads, + quad ); + ++actualNumberOfQuads; // Update the size of the highlighted text. maxHighlightX = mVisualModel->mControlSize.width; @@ -1965,15 +1980,23 @@ void Controller::Impl::RepositionSelectionHandles() { const SelectionBoxInfo& info = *it; - mEventData->mDecorator->AddHighlight( 0.f, - info.lineOffset, - info.minX, - info.lineOffset + info.lineHeight ); + quad.x = 0.f; + quad.y = info.lineOffset; + quad.z = info.minX; + quad.w = info.lineOffset + info.lineHeight; + + mEventData->mDecorator->AddHighlight( actualNumberOfQuads, + quad ); + ++actualNumberOfQuads; - mEventData->mDecorator->AddHighlight( info.maxX, - info.lineOffset, - mVisualModel->mControlSize.width, - info.lineOffset + info.lineHeight ); + quad.x = info.maxX; + quad.y = info.lineOffset; + quad.z = mVisualModel->mControlSize.width; + quad.w = info.lineOffset + info.lineHeight; + + mEventData->mDecorator->AddHighlight( actualNumberOfQuads, + quad ); + ++actualNumberOfQuads; } // Update the size of the highlighted text. @@ -1990,11 +2013,15 @@ void Controller::Impl::RepositionSelectionHandles() if( boxifyBegin ) { + quad.x = 0.f; + quad.y = lastSelectionBoxLineInfo.lineOffset; + quad.z = lastSelectionBoxLineInfo.minX; + quad.w = lastSelectionBoxLineInfo.lineOffset + lastSelectionBoxLineInfo.lineHeight; + // Boxify at the beginning of the line. - mEventData->mDecorator->AddHighlight( 0.f, - lastSelectionBoxLineInfo.lineOffset, - lastSelectionBoxLineInfo.minX, - lastSelectionBoxLineInfo.lineOffset + lastSelectionBoxLineInfo.lineHeight ); + mEventData->mDecorator->AddHighlight( actualNumberOfQuads, + quad ); + ++actualNumberOfQuads; // Update the size of the highlighted text. minHighlightX = 0.f; @@ -2002,17 +2029,24 @@ void Controller::Impl::RepositionSelectionHandles() if( boxifyEnd ) { + quad.x = lastSelectionBoxLineInfo.maxX; + quad.y = lastSelectionBoxLineInfo.lineOffset; + quad.z = mVisualModel->mControlSize.width; + quad.w = lastSelectionBoxLineInfo.lineOffset + lastSelectionBoxLineInfo.lineHeight; + // Boxify at the end of the line. - mEventData->mDecorator->AddHighlight( lastSelectionBoxLineInfo.maxX, - lastSelectionBoxLineInfo.lineOffset, - mVisualModel->mControlSize.width, - lastSelectionBoxLineInfo.lineOffset + lastSelectionBoxLineInfo.lineHeight ); + mEventData->mDecorator->AddHighlight( actualNumberOfQuads, + quad ); + ++actualNumberOfQuads; // Update the size of the highlighted text. maxHighlightX = mVisualModel->mControlSize.width; } } + // Set the actual number of quads. + mEventData->mDecorator->ResizeHighlightQuads( actualNumberOfQuads ); + // Sets the highlight's size and position. In decorator's coords. // The highlight's height has been calculated above (before 'boxifying' the highlight). highLightSize.width = maxHighlightX - minHighlightX;