From 522fdef5220890d655c8bb777b15574667a931b6 Mon Sep 17 00:00:00 2001 From: Victor Cebollada Date: Tue, 28 Jul 2015 09:43:37 +0100 Subject: [PATCH] Underline predictive text. Change-Id: I4675891596c6db239e4f58a5c372ad18fd4d2194 Signed-off-by: Victor Cebollada --- .../internal/atlas-manager/atlas-manager-impl.cpp | 55 +++------- .../internal/atlas-manager/atlas-manager-impl.h | 10 +- .../internal/atlas-manager/atlas-manager.cpp | 8 -- .../internal/atlas-manager/atlas-manager.h | 13 --- dali-toolkit/internal/text/glyph-run.h | 48 +++++++++ .../internal/text/layouts/layout-engine.cpp | 18 ++-- dali-toolkit/internal/text/line-run.h | 6 +- .../rendering/atlas/atlas-glyph-manager-impl.h | 4 +- .../text/rendering/atlas/text-atlas-renderer.cpp | 113 +++++++++++++++------ dali-toolkit/internal/text/text-controller.cpp | 21 +++- dali-toolkit/internal/text/text-definitions.h | 1 + dali-toolkit/internal/text/text-io.cpp | 2 +- dali-toolkit/internal/text/text-view-interface.h | 19 ++++ dali-toolkit/internal/text/text-view.cpp | 27 ++++- dali-toolkit/internal/text/text-view.h | 12 +++ dali-toolkit/internal/text/visual-model-impl.cpp | 15 ++- dali-toolkit/internal/text/visual-model-impl.h | 14 +++ 17 files changed, 261 insertions(+), 125 deletions(-) create mode 100644 dali-toolkit/internal/text/glyph-run.h diff --git a/dali-toolkit/internal/atlas-manager/atlas-manager-impl.cpp b/dali-toolkit/internal/atlas-manager/atlas-manager-impl.cpp index 3e69856..bfcf1fa 100644 --- a/dali-toolkit/internal/atlas-manager/atlas-manager-impl.cpp +++ b/dali-toolkit/internal/atlas-manager/atlas-manager-impl.cpp @@ -489,16 +489,22 @@ void AtlasManager::StitchMesh( Toolkit::AtlasManager::Mesh2D& first, const Toolkit::AtlasManager::Mesh2D& second, bool optimize ) { - uint32_t vc = first.mVertices.Size(); + const uint32_t verticesCount = first.mVertices.Size(); + first.mVertices.Insert( first.mVertices.End(), + second.mVertices.Begin(), + second.mVertices.End() ); - for ( uint32_t v = 0; v < second.mVertices.Size(); ++v ) - { - first.mVertices.PushBack( second.mVertices[ v ] ); - } + const uint32_t indicesCount = first.mIndices.Size(); + first.mIndices.Insert( first.mIndices.End(), + second.mIndices.Begin(), + second.mIndices.End() ); - for ( uint32_t i = 0; i < second.mIndices.Size(); ++i ) + for( Vector::Iterator it = first.mIndices.Begin() + indicesCount, + endIt = first.mIndices.End(); + it != endIt; + ++it ) { - first.mIndices.PushBack( second.mIndices[ i ] + vc ); + *it += verticesCount; } if ( optimize ) @@ -509,41 +515,6 @@ void AtlasManager::StitchMesh( Toolkit::AtlasManager::Mesh2D& first, } } -void AtlasManager::StitchMesh( const Toolkit::AtlasManager::Mesh2D& first, - const Toolkit::AtlasManager::Mesh2D& second, - Toolkit::AtlasManager::Mesh2D& out, - bool optimize ) -{ - uint32_t vc = first.mVertices.Size(); - - for ( uint32_t v = 0; v < vc; ++v ) - { - out.mVertices.PushBack( first.mVertices[ v ] ); - } - - for ( uint32_t v = 0; v < second.mVertices.Size(); ++v ) - { - out.mVertices.PushBack( second.mVertices[ v ] ); - } - - for ( uint32_t i = 0; i < first.mIndices.Size(); ++i ) - { - out.mIndices.PushBack( first.mIndices[ i ] ); - } - - for ( uint32_t i = 0; i < second.mIndices.Size(); ++i ) - { - out.mIndices.PushBack( second.mIndices[ i ] + vc ); - } - - if ( optimize ) - { - Toolkit::AtlasManager::Mesh2D optimizedMesh; - OptimizeMesh( out, optimizedMesh ); - out = optimizedMesh; - } -} - void AtlasManager::UploadImage( const BufferImage& image, const AtlasSlotDescriptor& desc ) { diff --git a/dali-toolkit/internal/atlas-manager/atlas-manager-impl.h b/dali-toolkit/internal/atlas-manager/atlas-manager-impl.h index b22f709..5b301f0 100644 --- a/dali-toolkit/internal/atlas-manager/atlas-manager-impl.h +++ b/dali-toolkit/internal/atlas-manager/atlas-manager-impl.h @@ -122,14 +122,6 @@ public: bool optimize ); /** - * @copydoc Toolkit::AtlasManager::StitchMesh - */ - void StitchMesh( const Toolkit::AtlasManager::Mesh2D& first, - const Toolkit::AtlasManager::Mesh2D& second, - Toolkit::AtlasManager::Mesh2D& out, - bool optimize ); - - /** * @copydoc Toolkit::AtlasManager::Remove */ bool Remove( ImageId id ); @@ -249,4 +241,4 @@ inline Internal::AtlasManager& GetImplementation(Toolkit::AtlasManager& manager) } // namespace Dali - #endif // __DALI_TOOLKIT_ATLAS_MANAGER_IMPL_H__ \ No newline at end of file + #endif // __DALI_TOOLKIT_ATLAS_MANAGER_IMPL_H__ diff --git a/dali-toolkit/internal/atlas-manager/atlas-manager.cpp b/dali-toolkit/internal/atlas-manager/atlas-manager.cpp index e6b041c..849b27d 100644 --- a/dali-toolkit/internal/atlas-manager/atlas-manager.cpp +++ b/dali-toolkit/internal/atlas-manager/atlas-manager.cpp @@ -85,14 +85,6 @@ void AtlasManager::StitchMesh( Mesh2D& first, GetImplementation(*this).StitchMesh( first, second, optimize ); } -void AtlasManager::StitchMesh( const Mesh2D& first, - const Mesh2D& second, - Mesh2D& out, - bool optimize ) -{ - GetImplementation(*this).StitchMesh( first, second, out, optimize ); -} - Dali::Atlas AtlasManager::GetAtlasContainer( AtlasId atlas ) const { return GetImplementation(*this).GetAtlasContainer( atlas ); diff --git a/dali-toolkit/internal/atlas-manager/atlas-manager.h b/dali-toolkit/internal/atlas-manager/atlas-manager.h index 532be6f..2c7f192 100644 --- a/dali-toolkit/internal/atlas-manager/atlas-manager.h +++ b/dali-toolkit/internal/atlas-manager/atlas-manager.h @@ -313,19 +313,6 @@ public: bool optimize = false ); /** - * @brief Combine two meshes, outputting the result into a new mesh - * - * @param[in] first First mesh - * @param[in] second Second mesh - * @param[in] optimize should we optimize vertex data - * @param[out] out resulting mesh - */ - void StitchMesh( const Mesh2D& first, - const Mesh2D& second, - Mesh2D& out, - bool optimize = false ); - - /** * @brief Get the BufferImage containing an atlas * * @param[in] atlas AtlasId returned when atlas was created diff --git a/dali-toolkit/internal/text/glyph-run.h b/dali-toolkit/internal/text/glyph-run.h new file mode 100644 index 0000000..47ebfb8 --- /dev/null +++ b/dali-toolkit/internal/text/glyph-run.h @@ -0,0 +1,48 @@ +#ifndef __DALI_TOOLKIT_TEXT_GLYPH_RUN_H__ +#define __DALI_TOOLKIT_TEXT_GLYPH_RUN_H__ + +/* + * Copyright (c) 2015 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// INTERNAL INCLUDES +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Text +{ + +/** + * @brief A run of consecutive glyphs. + */ +struct GlyphRun +{ + GlyphIndex glyphIndex; ///< Index to the first glyph. + Length numberOfGlyphs; ///< Number of glyphs in the run. +}; + +} // namespace Text + +} // namespace Toolkit + +} // namespace Dali + +#endif // __DALI_TOOLKIT_TEXT_GLYPH_RUN_H__ diff --git a/dali-toolkit/internal/text/layouts/layout-engine.cpp b/dali-toolkit/internal/text/layouts/layout-engine.cpp index 25ea95a..5a28904 100644 --- a/dali-toolkit/internal/text/layouts/layout-engine.cpp +++ b/dali-toolkit/internal/text/layouts/layout-engine.cpp @@ -527,11 +527,11 @@ struct LayoutEngine::Impl penY -= layout.ascender - lineRun.descender; - ellipsisLayout.glyphIndex = lineRun.glyphIndex; + ellipsisLayout.glyphIndex = lineRun.glyphRun.glyphIndex; } else { - lineRun.glyphIndex = 0u; + lineRun.glyphRun.glyphIndex = 0u; ellipsisLayout.glyphIndex = 0u; } @@ -540,7 +540,7 @@ struct LayoutEngine::Impl currentParagraphDirection, true ); - lineRun.numberOfGlyphs = ellipsisLayout.numberOfGlyphs; + lineRun.glyphRun.numberOfGlyphs = ellipsisLayout.numberOfGlyphs; lineRun.characterRun.characterIndex = ellipsisLayout.characterIndex; lineRun.characterRun.numberOfCharacters = ellipsisLayout.numberOfCharacters; lineRun.width = ellipsisLayout.length; @@ -553,10 +553,10 @@ struct LayoutEngine::Impl actualSize.width = layoutParameters.boundingBox.width; actualSize.height += ( lineRun.ascender + -lineRun.descender ); - SetGlyphPositions( layoutParameters.glyphsBuffer + lineRun.glyphIndex, + SetGlyphPositions( layoutParameters.glyphsBuffer + lineRun.glyphRun.glyphIndex, ellipsisLayout.numberOfGlyphs, penY, - glyphPositions.Begin() + lineRun.glyphIndex ); + glyphPositions.Begin() + lineRun.glyphRun.glyphIndex ); if( 0u != numberOfLines ) { @@ -576,8 +576,8 @@ struct LayoutEngine::Impl const bool isLastLine = index + layout.numberOfGlyphs == layoutParameters.totalNumberOfGlyphs; LineRun lineRun; - lineRun.glyphIndex = index; - lineRun.numberOfGlyphs = layout.numberOfGlyphs; + lineRun.glyphRun.glyphIndex = index; + lineRun.glyphRun.numberOfGlyphs = layout.numberOfGlyphs; lineRun.characterRun.characterIndex = layout.characterIndex; lineRun.characterRun.numberOfCharacters = layout.numberOfCharacters; if( isLastLine && !layoutParameters.isLastNewParagraph ) @@ -635,8 +635,8 @@ struct LayoutEngine::Impl mFontClient.GetFontMetrics( glyphInfo.fontId, fontMetrics ); LineRun lineRun; - lineRun.glyphIndex = 0u; - lineRun.numberOfGlyphs = 0u; + lineRun.glyphRun.glyphIndex = 0u; + lineRun.glyphRun.numberOfGlyphs = 0u; lineRun.characterRun.characterIndex = 0u; lineRun.characterRun.numberOfCharacters = 0u; lineRun.width = 0.f; diff --git a/dali-toolkit/internal/text/line-run.h b/dali-toolkit/internal/text/line-run.h index 6909182..52df79e 100644 --- a/dali-toolkit/internal/text/line-run.h +++ b/dali-toolkit/internal/text/line-run.h @@ -20,6 +20,7 @@ // INTERNAL INCLUDES #include +#include namespace Dali { @@ -35,9 +36,8 @@ namespace Text */ struct LineRun { - GlyphIndex glyphIndex; ///< The initial glyph index. - Length numberOfGlyphs; ///< The number of glyphs of the run. - CharacterRun characterRun; ///< The initial character and the number of characters. + GlyphRun glyphRun; ///< The initial glyph index and the number of glyphs of the run. + CharacterRun characterRun; ///< The initial character index and the number of characters of the run. float width; ///< The line's width. float ascender; ///< The line's ascender. float descender; ///< The line's descender. diff --git a/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.h b/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.h index ce937a8..5ba6740 100644 --- a/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.h +++ b/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.h @@ -1,4 +1,3 @@ - #ifndef __DALI_TOOLKIT_ATLAS_GLYPH_MANAGER_IMPL_H__ #define __DALI_TOOLKIT_ATLAS_GLYPH_MANAGER_IMPL_H__ @@ -185,5 +184,4 @@ inline Internal::AtlasGlyphManager& GetImplementation(Toolkit::AtlasGlyphManager } // namespace Dali - - #endif // __DALI_TOOLKIT_ATLAS_GLYPH_MANAGER_IMPL_H__ +#endif // __DALI_TOOLKIT_ATLAS_GLYPH_MANAGER_IMPL_H__ diff --git a/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp b/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp index 2e94ce1..42961ce 100644 --- a/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp +++ b/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp @@ -30,6 +30,7 @@ // INTERNAL INCLUDES #include +#include #include #include @@ -72,6 +73,10 @@ struct AtlasRenderer::Impl : public ConnectionTracker FrameBufferImage mBuffer; }; + /** + * brief Struct used to generate the underline mesh. + * There is one Extent per line of text. + */ struct Extent { Extent() @@ -143,8 +148,30 @@ struct AtlasRenderer::Impl : public ConnectionTracker mQuadIndexFormat[ "indices" ] = Property::INTEGER; } + bool IsGlyphUnderlined( GlyphIndex index, + const Vector& underlineRuns ) + { + // TODO: At the moment it works because we always traverse the glyphs starting from the beginning + // and there is only one glyph run! If there are more they should be ordered. + + for( Vector::ConstIterator it = underlineRuns.Begin(), + endIt = underlineRuns.End(); + it != endIt; + ++it ) + { + const GlyphRun& run = *it; + + if( ( run.glyphIndex <= index ) && ( index < run.glyphIndex + run.numberOfGlyphs ) ) + { + return true; + } + } + + return false; + } + void AddGlyphs( Text::ViewInterface& view, - const std::vector& positions, + const Vector& positions, const Vector& glyphs, int depth ) { @@ -155,18 +182,29 @@ struct AtlasRenderer::Impl : public ConnectionTracker mDepth = depth; const Vector2& actorSize( view.GetControlSize() ); - Vector2 halfActorSize( actorSize * 0.5f ); + const Vector2 halfActorSize( actorSize * 0.5f ); const Vector4& textColor( view.GetTextColor() ); const Vector2& shadowOffset( view.GetShadowOffset() ); const Vector4& shadowColor( view.GetShadowColor() ); - bool underlineEnabled( view.IsUnderlineEnabled() ); + const bool underlineEnabled( view.IsUnderlineEnabled() ); const Vector4& underlineColor( view.GetUnderlineColor() ); - float underlineHeight( view.GetUnderlineHeight() ); + const float underlineHeight( view.GetUnderlineHeight() ); + + // Get the underline runs. + const Length numberOfUnderlineRuns = view.GetNumberOfUnderlineRuns(); + Vector underlineRuns; + underlineRuns.Resize( numberOfUnderlineRuns ); + view.GetUnderlineRuns( underlineRuns.Begin(), + 0u, + numberOfUnderlineRuns ); + + bool thereAreUnderlinedGlyphs = false; float currentUnderlinePosition = ZERO; float currentUnderlineThickness = underlineHeight; uint32_t currentBlockSize = 0; FontId lastFontId = 0; + FontId lastUnderlinedFontId = 0; Style style = STYLE_NORMAL; if ( fabsf( shadowOffset.x ) > Math::MACHINE_EPSILON_1 || fabsf( shadowOffset.y ) > Math::MACHINE_EPSILON_1 ) @@ -179,16 +217,20 @@ struct AtlasRenderer::Impl : public ConnectionTracker // Avoid emptying mTextCache (& removing references) until after incremented references for the new text Vector< TextCacheEntry > newTextCache; const GlyphInfo* const glyphsBuffer = glyphs.Begin(); + const Vector2* const positionsBuffer = positions.Begin(); for( uint32_t i = 0, glyphSize = glyphs.Size(); i < glyphSize; ++i ) { const GlyphInfo& glyph = *( glyphsBuffer + i ); + const bool underlineGlyph = underlineEnabled || IsGlyphUnderlined( i, underlineRuns ); + thereAreUnderlinedGlyphs = thereAreUnderlinedGlyphs || underlineGlyph; + // No operation for white space if ( glyph.width && glyph.height ) { // Are we still using the same fontId as previous - if ( glyph.fontId != lastFontId ) + if ( underlineGlyph && ( glyph.fontId != lastUnderlinedFontId ) ) { // We need to fetch fresh font underline metrics FontMetrics fontMetrics; @@ -221,7 +263,9 @@ struct AtlasRenderer::Impl : public ConnectionTracker // Move offset down by one ( EFL behavior ) currentUnderlinePosition = ONE; } - } + + lastUnderlinedFontId = glyph.fontId; + } // underline if ( !mGlyphManager.Cached( glyph.fontId, glyph.index, slot ) ) { @@ -277,7 +321,7 @@ struct AtlasRenderer::Impl : public ConnectionTracker } // Move the origin (0,0) of the mesh to the center of the actor - Vector2 position = positions[ i ] - halfActorSize; + Vector2 position = *( positionsBuffer + i ) - halfActorSize; // Generate mesh data for this quad, plugging in our supplied position AtlasManager::Mesh2D newMesh; @@ -293,6 +337,7 @@ struct AtlasRenderer::Impl : public ConnectionTracker extents, textColor, position.y + glyph.yBearing, + underlineGlyph, currentUnderlinePosition, currentUnderlineThickness, slot ); @@ -304,7 +349,7 @@ struct AtlasRenderer::Impl : public ConnectionTracker RemoveText(); mTextCache.Swap( newTextCache ); - if ( underlineEnabled ) + if( thereAreUnderlinedGlyphs ) { // Check to see if any of the text needs an underline GenerateUnderlines( meshContainer, extents, underlineColor, textColor ); @@ -396,6 +441,7 @@ struct AtlasRenderer::Impl : public ConnectionTracker Vector< Extent >& extents, const Vector4& color, float baseLine, + bool underlineGlyph, float underlinePosition, float underlineThickness, AtlasManager::AtlasSlot& slot ) @@ -416,14 +462,19 @@ struct AtlasRenderer::Impl : public ConnectionTracker { // Stitch the mesh to the existing mesh and adjust any extents mGlyphManager.StitchMesh( mIt->mMesh, newMesh ); - AdjustExtents( extents, - meshContainer, - index, - left, - right, - baseLine, - underlinePosition, - underlineThickness ); + + if( underlineGlyph ) + { + AdjustExtents( extents, + meshContainer, + index, + left, + right, + baseLine, + underlinePosition, + underlineThickness ); + } + return; } } @@ -435,16 +486,18 @@ struct AtlasRenderer::Impl : public ConnectionTracker meshRecord.mColor = color; meshContainer.push_back( meshRecord ); - // Adjust extents for this new meshrecord - AdjustExtents( extents, - meshContainer, - meshContainer.size() - 1u, - left, - right, - baseLine, - underlinePosition, - underlineThickness ); - + if( underlineGlyph ) + { + // Adjust extents for this new meshrecord + AdjustExtents( extents, + meshContainer, + meshContainer.size() - 1u, + left, + right, + baseLine, + underlinePosition, + underlineThickness ); + } } } @@ -756,15 +809,15 @@ Actor AtlasRenderer::Render( Text::ViewInterface& view, int depth ) Vector glyphs; glyphs.Resize( numberOfGlyphs ); - std::vector positions; - positions.resize( numberOfGlyphs ); + Vector positions; + positions.Resize( numberOfGlyphs ); numberOfGlyphs = view.GetGlyphs( glyphs.Begin(), - &positions[0], + positions.Begin(), 0u, numberOfGlyphs ); glyphs.Resize( numberOfGlyphs ); - positions.resize( numberOfGlyphs ); + positions.Resize( numberOfGlyphs ); mImpl->AddGlyphs( view, positions, diff --git a/dali-toolkit/internal/text/text-controller.cpp b/dali-toolkit/internal/text/text-controller.cpp index 9d0cf87..a843feb 100644 --- a/dali-toolkit/internal/text/text-controller.cpp +++ b/dali-toolkit/internal/text/text-controller.cpp @@ -1198,6 +1198,9 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ this, text.c_str(), (COMMIT == type ? "COMMIT" : "PRE_EDIT"), mImpl->mEventData->mPrimaryCursorPosition, mImpl->mEventData->mPreEditFlag, mImpl->mEventData->mPreEditStartPosition, mImpl->mEventData->mPreEditLength ); + // TODO: At the moment the underline runs are only for pre-edit. + mImpl->mVisualModel->mUnderlineRuns.Clear(); + Vector utf32Characters; Length characterCount( 0u ); @@ -1255,7 +1258,7 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ } else // PRE_EDIT { - if( ! mImpl->mEventData->mPreEditFlag ) + if( !mImpl->mEventData->mPreEditFlag ) { DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Entered PreEdit state" ); @@ -1266,6 +1269,22 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ mImpl->mEventData->mPreEditLength = utf32Characters.Count(); mImpl->mEventData->mPreEditFlag = true; + // Add the underline for the pre-edit text. + const GlyphIndex* const charactersToGlyphBuffer = mImpl->mVisualModel->mCharactersToGlyph.Begin(); + const Length* const glyphsPerCharacterBuffer = mImpl->mVisualModel->mGlyphsPerCharacter.Begin(); + + const GlyphIndex glyphStart = *( charactersToGlyphBuffer + mImpl->mEventData->mPreEditStartPosition ); + const CharacterIndex lastPreEditCharacter = mImpl->mEventData->mPreEditStartPosition + ( ( mImpl->mEventData->mPreEditLength > 0u ) ? mImpl->mEventData->mPreEditLength - 1u : 0u ); + const Length numberOfGlyphsLastCharacter = *( glyphsPerCharacterBuffer + lastPreEditCharacter ); + const GlyphIndex glyphEnd = *( charactersToGlyphBuffer + lastPreEditCharacter ) + ( numberOfGlyphsLastCharacter > 1u ? numberOfGlyphsLastCharacter - 1u : 0u ); + + GlyphRun underlineRun; + underlineRun.glyphIndex = glyphStart; + underlineRun.numberOfGlyphs = 1u + glyphEnd - glyphStart; + + // TODO: At the moment the underline runs are only for pre-edit. + mImpl->mVisualModel->mUnderlineRuns.PushBack( underlineRun ); + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "mPreEditStartPosition %d mPreEditLength %d\n", mImpl->mEventData->mPreEditStartPosition, mImpl->mEventData->mPreEditLength ); } } diff --git a/dali-toolkit/internal/text/text-definitions.h b/dali-toolkit/internal/text/text-definitions.h index f93ffd7..85888b0 100644 --- a/dali-toolkit/internal/text/text-definitions.h +++ b/dali-toolkit/internal/text/text-definitions.h @@ -51,6 +51,7 @@ typedef TextAbstraction::CharacterDirection CharacterDirection; ///< The charact typedef uint32_t GlyphIndex; ///< An index into an array of glyphs. typedef uint32_t ScriptRunIndex; ///< An index into an array of script runs. typedef uint32_t FontRunIndex; ///< An index into an array of font runs. +typedef uint32_t UnderlineRunIndex; ///< An index into an array of underline runs. typedef uint32_t BidirectionalRunIndex; ///< An index into an array of font runs. typedef uint32_t LineIndex; ///< An index into an array of lines. diff --git a/dali-toolkit/internal/text/text-io.cpp b/dali-toolkit/internal/text/text-io.cpp index f4bd3f2..99f8a8c 100644 --- a/dali-toolkit/internal/text/text-io.cpp +++ b/dali-toolkit/internal/text/text-io.cpp @@ -93,7 +93,7 @@ std::ostream& operator<< (std::ostream& o, const Vector& lineRuns) for( unsigned int i=0; i9 Characters: 0->9 (10)" for a ten character run staring from beginning of the model - o << "Line " << i << " Glyphs: " << lineRuns[i].glyphIndex << "->" << (lineRuns[i].glyphIndex + lineRuns[i].numberOfGlyphs ); + o << "Line " << i << " Glyphs: " << lineRuns[i].glyphRun.glyphIndex << "->" << (lineRuns[i].glyphRun.glyphIndex + lineRuns[i].glyphRun.numberOfGlyphs ); o << " Characters: " << lineRuns[i].characterRun.characterIndex << "->" << (lineRuns[i].characterRun.characterIndex + lineRuns[i].characterRun.numberOfCharacters ); o << " Width: " << lineRuns[i].width; o << " Ascender: " << lineRuns[i].ascender; diff --git a/dali-toolkit/internal/text/text-view-interface.h b/dali-toolkit/internal/text/text-view-interface.h index bcc7f22..56439d2 100644 --- a/dali-toolkit/internal/text/text-view-interface.h +++ b/dali-toolkit/internal/text/text-view-interface.h @@ -33,6 +33,8 @@ namespace Toolkit namespace Text { +struct GlyphRun; + /** * @brief Abstract interface to provide the information necessary displaying text. * @@ -129,6 +131,23 @@ public: */ virtual float GetUnderlineHeight() const = 0; + /** + * @brief Retrieves the number of underline runs. + * + * @return The number of underline runs. + */ + virtual Length GetNumberOfUnderlineRuns() const = 0; + + /** + * @brief Retrieves the underline runs. + * + * @param[out] underlineRuns Pointer to a buffer where the underline runs are copied. + * @param[in] index Index of the first underline run to be copied. + * @param[in] numberOfRuns Number of underline runs to be copied. + */ + virtual void GetUnderlineRuns( GlyphRun* underlineRuns, + UnderlineRunIndex index, + Length numberOfRuns ) const = 0; }; } // namespace Text diff --git a/dali-toolkit/internal/text/text-view.cpp b/dali-toolkit/internal/text/text-view.cpp index 4bee1c2..ea074fa 100644 --- a/dali-toolkit/internal/text/text-view.cpp +++ b/dali-toolkit/internal/text/text-view.cpp @@ -103,7 +103,7 @@ Length View::GetGlyphs( GlyphInfo* glyphs, // Otherwise use the given number of glyphs. if( lastLine.ellipsis ) { - numberOfLaidOutGlyphs = lastLine.glyphIndex + lastLine.numberOfGlyphs; + numberOfLaidOutGlyphs = lastLine.glyphRun.glyphIndex + lastLine.glyphRun.numberOfGlyphs; } else { @@ -141,7 +141,7 @@ Length View::GetGlyphs( GlyphInfo* glyphs, LineRun* line = lineBuffer + lineIndex; // Index of the last glyph of the line. - GlyphIndex lastGlyphIndexOfLine = line->glyphIndex + line->numberOfGlyphs - 1u; + GlyphIndex lastGlyphIndexOfLine = line->glyphRun.glyphIndex + line->glyphRun.numberOfGlyphs - 1u; // Add the alignment offset to the glyph's position. for( Length index = 0u; index < numberOfLaidOutGlyphs; ++index ) @@ -156,7 +156,7 @@ Length View::GetGlyphs( GlyphInfo* glyphs, if( lineIndex < numberOfLines ) { line = lineBuffer + lineIndex; - lastGlyphIndexOfLine = line->glyphIndex + line->numberOfGlyphs - 1u; + lastGlyphIndexOfLine = line->glyphRun.glyphIndex + line->glyphRun.numberOfGlyphs - 1u; } } } @@ -317,6 +317,27 @@ float View::GetUnderlineHeight() const return 0.0f; } +Length View::GetNumberOfUnderlineRuns() const +{ + if( mImpl->mVisualModel ) + { + return mImpl->mVisualModel->mUnderlineRuns.Count(); + } + + return 0u; +} + +void View::GetUnderlineRuns( GlyphRun* underlineRuns, + UnderlineRunIndex index, + Length numberOfRuns ) const +{ + if( mImpl->mVisualModel ) + { + mImpl->mVisualModel->GetUnderlineRuns( underlineRuns, + index, + numberOfRuns ); + } +} } // namespace Text diff --git a/dali-toolkit/internal/text/text-view.h b/dali-toolkit/internal/text/text-view.h index 2ab19b1..058ca9c 100644 --- a/dali-toolkit/internal/text/text-view.h +++ b/dali-toolkit/internal/text/text-view.h @@ -103,6 +103,18 @@ public: */ virtual float GetUnderlineHeight() const; + /** + * @copydoc Dali::Toolkit::Text::ViewInterface::GetNumberOfUnderlineRuns() + */ + virtual Length GetNumberOfUnderlineRuns() const; + + /** + * @copydoc Dali::Toolkit::Text::ViewInterface::GetUnderlineRuns() + */ + virtual void GetUnderlineRuns( GlyphRun* underlineRuns, + UnderlineRunIndex index, + Length numberOfRuns ) const; + private: // Undefined diff --git a/dali-toolkit/internal/text/visual-model-impl.cpp b/dali-toolkit/internal/text/visual-model-impl.cpp index bb7cdde..561beee 100644 --- a/dali-toolkit/internal/text/visual-model-impl.cpp +++ b/dali-toolkit/internal/text/visual-model-impl.cpp @@ -149,13 +149,13 @@ void VisualModel::GetNumberOfLines( GlyphIndex glyphIndex, { const LineRun& line = *it; - if( ( line.glyphIndex + line.numberOfGlyphs > glyphIndex ) && - ( lastGlyphIndex > line.glyphIndex ) ) + if( ( line.glyphRun.glyphIndex + line.glyphRun.numberOfGlyphs > glyphIndex ) && + ( lastGlyphIndex > line.glyphRun.glyphIndex ) ) { firstLineFound = true; ++numberOfLines; } - else if( lastGlyphIndex <= line.glyphIndex ) + else if( lastGlyphIndex <= line.glyphRun.glyphIndex ) { // nothing else to do. break; @@ -216,6 +216,15 @@ LineIndex VisualModel::GetLineOfCharacter( CharacterIndex characterIndex ) return index; } +void VisualModel::GetUnderlineRuns( GlyphRun* underlineRuns, + UnderlineRunIndex index, + Length numberOfRuns ) const +{ + memcpy( underlineRuns, + mUnderlineRuns.Begin() + index, + numberOfRuns * sizeof( GlyphRun ) ); +} + void VisualModel::SetNaturalSize( const Vector2& size ) { mNaturalSize = size; diff --git a/dali-toolkit/internal/text/visual-model-impl.h b/dali-toolkit/internal/text/visual-model-impl.h index 32ab386..0717582 100644 --- a/dali-toolkit/internal/text/visual-model-impl.h +++ b/dali-toolkit/internal/text/visual-model-impl.h @@ -152,6 +152,19 @@ public: */ LineIndex GetLineOfCharacter( CharacterIndex characterIndex ); + // Underline runs + + /** + * @brief Retrieves the underline runs. + * + * @param[out] underlineRuns Pointer to a buffer where the underline runs are copied. + * @param[in] index Index of the first underline run to be copied. + * @param[in] numberOfRuns Number of underline runs to be copied. + */ + void GetUnderlineRuns( GlyphRun* underlineRuns, + UnderlineRunIndex index, + Length numberOfRuns ) const; + // Size interface /** @@ -300,6 +313,7 @@ public: Vector mGlyphsPerCharacter; ///< For each character, the number of glyphs that are shaped. Vector mGlyphPositions; ///< For each glyph, the position. Vector mLines; ///< The laid out lines. + Vector mUnderlineRuns; ///< Runs of glyphs that are underlined. Vector2 mControlSize; ///< The size of the UI control the decorator is adding it's decorations to. Vector4 mTextColor; ///< The text color -- 2.7.4