From: Richard Huang Date: Thu, 7 Dec 2017 13:33:27 +0000 (+0000) Subject: Text outline support in TextField & TextEditor X-Git-Tag: dali_1.3.4~9^2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=bef7b82cd945f4d2fd3b4d776184c1fc0851c8c6 Text outline support in TextField & TextEditor Measured using memps on TM1 target by creating 500 TextFields. Memory consumption is increased by 9% after outline is enabled. Without outiline, the memory comsumption is almost the same as before. TextField with text only (no outline): Before applying this patch: PID CODE DATA PEAK PSS 3D GEM(PSS) 11272 13572 75120 88692 76920 58860 5568 After applying this patch: PID CODE DATA PEAK PSS 3D GEM(PSS) 5782 13580 75244 88824 77055 58508 5568 TextField with text and outline: After applying this patch: PID CODE DATA PEAK PSS 3D GEM(PSS) 5851 13588 82056 95644 83874 63364 5568 Change-Id: I9838fb0867102e920bcc07650ff5c3a8903a7e24 --- diff --git a/dali-toolkit/internal/text/markup-processor-helper-functions.cpp b/dali-toolkit/internal/text/markup-processor-helper-functions.cpp index 8af6140..76d9a6a 100644 --- a/dali-toolkit/internal/text/markup-processor-helper-functions.cpp +++ b/dali-toolkit/internal/text/markup-processor-helper-functions.cpp @@ -109,6 +109,13 @@ void FloatToString( float value, std::string& floatStr ) floatStr = ss.str(); } +void UintToString( unsigned int value, std::string& uIntStr ) +{ + std::stringstream ss; + ss << value; + uIntStr = ss.str(); +} + void UintColorToVector4( unsigned int color, Vector4& retColor ) { retColor.a = static_cast( ( color & 0xFF000000 ) >> 24u ) / 255.f; diff --git a/dali-toolkit/internal/text/markup-processor-helper-functions.h b/dali-toolkit/internal/text/markup-processor-helper-functions.h index 45f586c..d1ecbc8 100644 --- a/dali-toolkit/internal/text/markup-processor-helper-functions.h +++ b/dali-toolkit/internal/text/markup-processor-helper-functions.h @@ -121,6 +121,14 @@ float StringToFloat( const char* const floatStr ); void FloatToString( float value, std::string& floatStr ); /** + * @brief Converts an unsigned int into a string. + * + * @param[in] value The unsigned int value. + * @param[out] uIntStr The string. + */ +void UintToString( unsigned int value, std::string& uIntStr ); + +/** * @brief Converts an ARGB color packed in 4 byte unsigned int into a Vector4 color used in Dali. * * @param[in] color An ARGB color packed in an unsigned int. diff --git a/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.cpp b/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.cpp index 0d72be9..957fd8e 100644 --- a/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.cpp +++ b/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.cpp @@ -44,6 +44,7 @@ AtlasGlyphManager::AtlasGlyphManager() } void AtlasGlyphManager::Add( const Text::GlyphInfo& glyph, + const uint32_t outlineWidth, const PixelData& bitmap, Dali::Toolkit::AtlasManager::AtlasSlot& slot ) { @@ -62,6 +63,7 @@ void AtlasGlyphManager::Add( const Text::GlyphInfo& glyph, GlyphRecordEntry record; record.mIndex = glyph.index; + record.mOutlineWidth = outlineWidth; record.mImageId = slot.mImageId; record.mCount = 1; @@ -98,6 +100,7 @@ void AtlasGlyphManager::GenerateMeshData( uint32_t imageId, bool AtlasGlyphManager::IsCached( Text::FontId fontId, Text::GlyphIndex index, + uint32_t outlineWidth, Dali::Toolkit::AtlasManager::AtlasSlot& slot ) { for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin(); @@ -110,7 +113,7 @@ bool AtlasGlyphManager::IsCached( Text::FontId fontId, glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End(); ++glyphRecordIt ) { - if ( glyphRecordIt->mIndex == index ) + if ( glyphRecordIt->mIndex == index && glyphRecordIt->mOutlineWidth == outlineWidth ) { slot.mImageId = glyphRecordIt->mImageId; slot.mAtlasId = mAtlasManager.GetAtlas( slot.mImageId ); @@ -171,7 +174,7 @@ const Toolkit::AtlasGlyphManager::Metrics& AtlasGlyphManager::GetMetrics() return mMetrics; } -void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, int32_t delta ) +void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, uint32_t outlineWidth, int32_t delta ) { if( 0 != delta ) { @@ -187,7 +190,7 @@ void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, Text::GlyphIn glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End(); ++glyphRecordIt ) { - if ( glyphRecordIt->mIndex == index ) + if ( glyphRecordIt->mIndex == index && glyphRecordIt->mOutlineWidth == outlineWidth ) { glyphRecordIt->mCount += delta; DALI_ASSERT_DEBUG( glyphRecordIt->mCount >= 0 && "Glyph ref-count should not be negative" ); 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 a2232f9..0d32834 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 @@ -51,6 +51,7 @@ public: struct GlyphRecordEntry { Text::GlyphIndex mIndex; + uint32_t mOutlineWidth; uint32_t mImageId; int32_t mCount; }; @@ -70,6 +71,7 @@ public: * @copydoc Toolkit::AtlasGlyphManager::Add */ void Add( const Text::GlyphInfo& glyph, + const uint32_t outlineWidth, const PixelData& bitmap, Dali::Toolkit::AtlasManager::AtlasSlot& slot ); @@ -85,6 +87,7 @@ public: */ bool IsCached( Text::FontId fontId, Text::GlyphIndex index, + uint32_t outlineWidth, Dali::Toolkit::AtlasManager::AtlasSlot& slot ); /** @@ -105,7 +108,7 @@ public: /** * @copydoc toolkit::AtlasGlyphManager::AdjustReferenceCount */ - void AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, int32_t delta ); + void AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, uint32_t outlineWidth, int32_t delta ); /** * @copydoc Toolkit::AtlasGlyphManager::GetTextures diff --git a/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.cpp b/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.cpp index 743bc6c..bd6850d 100644 --- a/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.cpp +++ b/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.cpp @@ -69,10 +69,11 @@ AtlasGlyphManager::AtlasGlyphManager(Internal::AtlasGlyphManager *impl) } void AtlasGlyphManager::Add( const Text::GlyphInfo& glyph, + const uint32_t outlineWidth, const PixelData& bitmap, AtlasManager::AtlasSlot& slot ) { - GetImplementation(*this).Add( glyph, bitmap, slot ); + GetImplementation(*this).Add( glyph, outlineWidth, bitmap, slot ); } void AtlasGlyphManager::GenerateMeshData( uint32_t imageId, @@ -86,9 +87,10 @@ void AtlasGlyphManager::GenerateMeshData( uint32_t imageId, bool AtlasGlyphManager::IsCached( Text::FontId fontId, Text::GlyphIndex index, + uint32_t outlineWidth, AtlasManager::AtlasSlot& slot ) { - return GetImplementation(*this).IsCached( fontId, index, slot ); + return GetImplementation(*this).IsCached( fontId, index, outlineWidth, slot ); } void AtlasGlyphManager::SetNewAtlasSize( uint32_t width, uint32_t height, uint32_t blockWidth, uint32_t blockHeight ) @@ -116,9 +118,9 @@ const Toolkit::AtlasGlyphManager::Metrics& AtlasGlyphManager::GetMetrics() return GetImplementation(*this).GetMetrics(); } -void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, int32_t delta ) +void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, uint32_t outlineWidth, int32_t delta ) { - GetImplementation(*this).AdjustReferenceCount( fontId, index, delta ); + GetImplementation(*this).AdjustReferenceCount( fontId, index, outlineWidth, delta ); } } // namespace Toolkit diff --git a/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.h b/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.h index 1bc058b..c41415e 100644 --- a/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.h +++ b/dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.h @@ -80,10 +80,12 @@ public: * @brief Ask Atlas Manager to add a glyph * * @param[in] glyph glyph to add to an atlas + * @param[in] outlineWidth the outline width of the glyph * @param[in] bitmap bitmap to use for glyph addition * @param[out] slot information returned by atlas manager for addition */ void Add( const Text::GlyphInfo& glyph, + const uint32_t outlineWidth, const PixelData& bitmap, AtlasManager::AtlasSlot& slot ); @@ -103,12 +105,14 @@ public: * * @param[in] fontId The font that this glyph comes from * @param[in] index The GlyphIndex of this glyph + * @param[in] outlineWidth The outline width of this glyph * @param[out] slot container holding information about the glyph( mImage = 0 indicates not being cached ) * * @return Whether glyph is cached or not ? */ bool IsCached( Text::FontId fontId, Text::GlyphIndex index, + uint32_t outlineWidth, AtlasManager::AtlasSlot& slot ); /** @@ -160,9 +164,10 @@ public: * * @param[in] fontId The font this image came from * @param[in] index The index of the glyph + * @param[in] outlineWidth The outline width of the glyph * @param[in] delta The adjustment to make to the reference count */ - void AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, int32_t delta ); + void AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, uint32_t outlineWidth, int32_t delta ); private: 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 54a746a..3ef1965 100644 --- a/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp +++ b/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp @@ -94,7 +94,7 @@ const float HALF( 0.5f ); const float ONE( 1.0f ); const uint32_t DEFAULT_ATLAS_WIDTH = 512u; const uint32_t DEFAULT_ATLAS_HEIGHT = 512u; -const int NO_OUTLINE( 0 ); +const uint32_t NO_OUTLINE = 0; } struct AtlasRenderer::Impl @@ -172,12 +172,14 @@ struct AtlasRenderer::Impl TextCacheEntry() : mFontId( 0 ), mIndex( 0 ), + mOutlineWidth( 0 ), mImageId( 0 ) { } FontId mFontId; Text::GlyphIndex mIndex; + uint32_t mOutlineWidth; uint32_t mImageId; }; @@ -211,9 +213,9 @@ struct AtlasRenderer::Impl return false; } - void CacheGlyph( const GlyphInfo& glyph, FontId lastFontId, AtlasManager::AtlasSlot& slot ) + void CacheGlyph( const GlyphInfo& glyph, FontId lastFontId, uint32_t outline, AtlasManager::AtlasSlot& slot ) { - bool glyphNotCached = !mGlyphManager.IsCached( glyph.fontId, glyph.index, slot ); // Check FontGlyphRecord vector for entry with glyph index and fontId + const bool glyphNotCached = !mGlyphManager.IsCached( glyph.fontId, glyph.index, outline, slot ); // Check FontGlyphRecord vector for entry with glyph index and fontId DALI_LOG_INFO( gLogFilter, Debug::Verbose, "AddGlyphs fontID[%u] glyphIndex[%u] [%s]\n", glyph.fontId, glyph.index, (glyphNotCached)?"not cached":"cached" ); @@ -242,62 +244,69 @@ struct AtlasRenderer::Impl // Create a new image for the glyph PixelData bitmap; + // Whether the glyph is an outline. + const bool isOutline = 0u != outline; + // Whether the current glyph is a color one. const bool isColorGlyph = mFontClient.IsColorGlyph( glyph.fontId, glyph.index ); - // Retrieve the emoji's bitmap. - TextAbstraction::FontClient::GlyphBufferData glyphBufferData; - glyphBufferData.width = isColorGlyph ? glyph.width : 0; // Desired width and height. - glyphBufferData.height = isColorGlyph ? glyph.height : 0; - - mFontClient.CreateBitmap( glyph.fontId, - glyph.index, - glyphBufferData, - NO_OUTLINE ); - - // Create the pixel data. - bitmap = PixelData::New( glyphBufferData.buffer, - glyph.width * glyph.height * GetBytesPerPixel( glyphBufferData.format ), - glyph.width, - glyph.height, - glyphBufferData.format, - PixelData::DELETE_ARRAY ); - - if( bitmap ) + if( !isOutline || ( isOutline && !isColorGlyph) ) { - // Ensure that the next image will fit into the current block size - if( bitmap.GetWidth() > blockSize.mNeededBlockWidth ) + // Retrieve the emoji's bitmap. + TextAbstraction::FontClient::GlyphBufferData glyphBufferData; + glyphBufferData.width = isColorGlyph ? glyph.width : 0; // Desired width and height. + glyphBufferData.height = isColorGlyph ? glyph.height : 0; + + mFontClient.CreateBitmap( glyph.fontId, + glyph.index, + glyphBufferData, + outline ); + + // Create the pixel data. + bitmap = PixelData::New( glyphBufferData.buffer, + glyphBufferData.width * glyphBufferData.height * GetBytesPerPixel( glyphBufferData.format ), + glyphBufferData.width, + glyphBufferData.height, + glyphBufferData.format, + PixelData::DELETE_ARRAY ); + + if( bitmap ) { - blockSize.mNeededBlockWidth = bitmap.GetWidth(); - } + // Ensure that the next image will fit into the current block size + if( bitmap.GetWidth() > blockSize.mNeededBlockWidth ) + { + blockSize.mNeededBlockWidth = bitmap.GetWidth(); + } - if( bitmap.GetHeight() > blockSize.mNeededBlockHeight ) - { - blockSize.mNeededBlockHeight = bitmap.GetHeight(); - } + if( bitmap.GetHeight() > blockSize.mNeededBlockHeight ) + { + blockSize.mNeededBlockHeight = bitmap.GetHeight(); + } - // If CheckAtlas in AtlasManager::Add can't fit the bitmap in the current atlas it will create a new atlas + // If CheckAtlas in AtlasManager::Add can't fit the bitmap in the current atlas it will create a new atlas - // Setting the block size and size of new atlas does not mean a new one will be created. An existing atlas may still surffice. - mGlyphManager.SetNewAtlasSize( DEFAULT_ATLAS_WIDTH, - DEFAULT_ATLAS_HEIGHT, - blockSize.mNeededBlockWidth, - blockSize.mNeededBlockHeight ); + // Setting the block size and size of new atlas does not mean a new one will be created. An existing atlas may still surffice. + mGlyphManager.SetNewAtlasSize( DEFAULT_ATLAS_WIDTH, + DEFAULT_ATLAS_HEIGHT, + blockSize.mNeededBlockWidth, + blockSize.mNeededBlockHeight ); - // Locate a new slot for our glyph - mGlyphManager.Add( glyph, bitmap, slot ); // slot will be 0 is glyph not added + // Locate a new slot for our glyph + mGlyphManager.Add( glyph, outline, bitmap, slot ); // slot will be 0 is glyph not added + } } } else { // We have 2+ copies of the same glyph - mGlyphManager.AdjustReferenceCount( glyph.fontId, glyph.index, 1/*increment*/ ); + mGlyphManager.AdjustReferenceCount( glyph.fontId, glyph.index, outline, 1 ); //increment } } void GenerateMesh( const GlyphInfo& glyph, const Vector2& position, const Vector4& color, + uint32_t outline, AtlasManager::AtlasSlot& slot, bool underlineGlyph, float currentUnderlinePosition, @@ -314,6 +323,7 @@ struct AtlasRenderer::Impl textCacheEntry.mFontId = glyph.fontId; textCacheEntry.mImageId = slot.mImageId; textCacheEntry.mIndex = glyph.index; + textCacheEntry.mOutlineWidth = outline; newTextCache.PushBack( textCacheEntry ); @@ -342,12 +352,12 @@ struct AtlasRenderer::Impl void CreateActors( const std::vector& meshContainer, const Size& textSize, - const Vector4& defaultColor, + const Vector4& color, const Vector4& shadowColor, const Vector2& shadowOffset, - Style style, Actor textControl, - Property::Index animatablePropertyIndex ) + Property::Index animatablePropertyIndex, + bool drawShadow ) { if( !mActor ) { @@ -365,14 +375,14 @@ struct AtlasRenderer::Impl { const MeshRecord& meshRecord = *it; - Actor actor = CreateMeshActor( textControl, animatablePropertyIndex, defaultColor, meshRecord, textSize, STYLE_NORMAL ); + Actor actor = CreateMeshActor( textControl, animatablePropertyIndex, color, meshRecord, textSize, STYLE_NORMAL ); // Whether the actor has renderers. const bool hasRenderer = actor.GetRendererCount() > 0u; // Create an effect if necessary if( hasRenderer && - ( style == STYLE_DROP_SHADOW ) ) + drawShadow ) { // Change the color of the vertices. for( Vector::Iterator vIt = meshRecord.mMesh.mVertices.Begin(), @@ -385,7 +395,7 @@ struct AtlasRenderer::Impl vertex.mColor = shadowColor; } - Actor shadowActor = CreateMeshActor(textControl, animatablePropertyIndex, defaultColor, meshRecord, textSize, STYLE_DROP_SHADOW ); + Actor shadowActor = CreateMeshActor(textControl, animatablePropertyIndex, color, meshRecord, textSize, STYLE_DROP_SHADOW ); #if defined(DEBUG_ENABLED) shadowActor.SetName( "Text Shadow renderable actor" ); #endif @@ -416,7 +426,15 @@ struct AtlasRenderer::Impl float minLineOffset ) { AtlasManager::AtlasSlot slot; + slot.mImageId = 0u; + slot.mAtlasId = 0u; + + AtlasManager::AtlasSlot slotOutline; + slotOutline.mImageId = 0u; + slotOutline.mAtlasId = 0u; + std::vector< MeshRecord > meshContainer; + std::vector< MeshRecord > meshContainerOutline; Vector< Extent > extents; mDepth = depth; @@ -424,9 +442,12 @@ struct AtlasRenderer::Impl const Vector2 halfTextSize( textSize * 0.5f ); const Vector2& shadowOffset( view.GetShadowOffset() ); const Vector4& shadowColor( view.GetShadowColor() ); - const bool underlineEnabled( view.IsUnderlineEnabled() ); + const bool underlineEnabled = view.IsUnderlineEnabled(); const Vector4& underlineColor( view.GetUnderlineColor() ); - const float underlineHeight( view.GetUnderlineHeight() ); + const float underlineHeight = view.GetUnderlineHeight(); + const unsigned int outlineWidth = view.GetOutlineWidth(); + const Vector4& outlineColor( view.GetOutlineColor() ); + const bool isOutline = 0u != outlineWidth; const bool useDefaultColor = ( NULL == colorsBuffer ); @@ -462,14 +483,14 @@ struct AtlasRenderer::Impl 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; + const bool isGlyphUnderlined = underlineEnabled || IsGlyphUnderlined( i, underlineRuns ); + thereAreUnderlinedGlyphs = thereAreUnderlinedGlyphs || isGlyphUnderlined; // No operation for white space if( glyph.width && glyph.height ) { // Are we still using the same fontId as previous - if( underlineGlyph && ( glyph.fontId != lastUnderlinedFontId ) ) + if( isGlyphUnderlined && ( glyph.fontId != lastUnderlinedFontId ) ) { // We need to fetch fresh font underline metrics FontMetrics fontMetrics; @@ -508,22 +529,37 @@ struct AtlasRenderer::Impl } // underline // Retrieves and caches the glyph's bitmap. - CacheGlyph( glyph, lastFontId, slot ); + CacheGlyph( glyph, lastFontId, NO_OUTLINE, slot ); + + // Retrieves and caches the outline glyph's bitmap. + if( isOutline ) + { + CacheGlyph( glyph, lastFontId, outlineWidth, slotOutline ); + } // Move the origin (0,0) of the mesh to the center of the actor const Vector2 position = *( positionsBuffer + i ) - halfTextSize - lineOffsetPosition; if ( 0u != slot.mImageId ) // invalid slot id, glyph has failed to be added to atlas { + Vector2 positionPlusOutlineOffset = position; + if( isOutline ) + { + // Add an offset to the text. + const float outlineWidthOffset = static_cast( outlineWidth ); + positionPlusOutlineOffset += Vector2( outlineWidthOffset, outlineWidthOffset ); + } + // Get the color of the character. const ColorIndex colorIndex = useDefaultColor ? 0u : *( colorIndicesBuffer + i ); const Vector4& color = ( useDefaultColor || ( 0u == colorIndex ) ) ? defaultColor : *( colorsBuffer + colorIndex - 1u ); GenerateMesh( glyph, - position, + positionPlusOutlineOffset, color, + NO_OUTLINE, slot, - underlineGlyph, + isGlyphUnderlined, currentUnderlinePosition, currentUnderlineThickness, meshContainer, @@ -532,6 +568,21 @@ struct AtlasRenderer::Impl lastFontId = glyph.fontId; // Prevents searching for existing blocksizes when string of the same fontId. } + + if( isOutline&& ( 0u != slotOutline.mImageId ) ) // invalid slot id, glyph has failed to be added to atlas + { + GenerateMesh( glyph, + position, + outlineColor, + outlineWidth, + slotOutline, + false, + currentUnderlinePosition, + currentUnderlineThickness, + meshContainerOutline, + newTextCache, + extents); + } } } // glyphs @@ -546,16 +597,34 @@ struct AtlasRenderer::Impl } // For each MeshData object, create a mesh actor and add to the renderable actor + bool isShadowDrawn = false; + if( !meshContainerOutline.empty() ) + { + const bool drawShadow = STYLE_DROP_SHADOW == style; + CreateActors( meshContainerOutline, + textSize, + outlineColor, + shadowColor, + shadowOffset, + textControl, + animatablePropertyIndex, + drawShadow ); + + isShadowDrawn = drawShadow; + } + + // For each MeshData object, create a mesh actor and add to the renderable actor if( !meshContainer.empty() ) { + const bool drawShadow = !isShadowDrawn && ( STYLE_DROP_SHADOW == style ); CreateActors( meshContainer, textSize, defaultColor, shadowColor, shadowOffset, - style, textControl, - animatablePropertyIndex ); + animatablePropertyIndex, + drawShadow ); } #if defined(DEBUG_ENABLED) @@ -586,7 +655,7 @@ struct AtlasRenderer::Impl { for( Vector< TextCacheEntry >::Iterator oldTextIter = mTextCache.Begin(); oldTextIter != mTextCache.End(); ++oldTextIter ) { - mGlyphManager.AdjustReferenceCount( oldTextIter->mFontId, oldTextIter->mIndex, -1/*decrement*/ ); + mGlyphManager.AdjustReferenceCount( oldTextIter->mFontId, oldTextIter->mIndex, oldTextIter->mOutlineWidth, -1/*decrement*/ ); } mTextCache.Resize( 0 ); } @@ -661,6 +730,7 @@ struct AtlasRenderer::Impl actor.SetSize( actorSize ); actor.RegisterProperty("uOffset", Vector2::ZERO ); actor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR ); + return actor; } diff --git a/dali-toolkit/internal/text/text-controller-impl.cpp b/dali-toolkit/internal/text/text-controller-impl.cpp index 874503d..566d747 100644 --- a/dali-toolkit/internal/text/text-controller-impl.cpp +++ b/dali-toolkit/internal/text/text-controller-impl.cpp @@ -1144,7 +1144,7 @@ float Controller::Impl::GetDefaultFontLineHeight() void Controller::Impl::OnCursorKeyEvent( const Event& event ) { - if( NULL == mEventData ) + if( NULL == mEventData || !IsShowingRealText() ) { // Nothing to do if there is no text input. return; diff --git a/dali-toolkit/internal/text/text-controller.cpp b/dali-toolkit/internal/text/text-controller.cpp index d054cbc..e0df4e4 100755 --- a/dali-toolkit/internal/text/text-controller.cpp +++ b/dali-toolkit/internal/text/text-controller.cpp @@ -1182,14 +1182,14 @@ const Vector4& Controller::GetOutlineColor() const return mImpl->mModel->mVisualModel->GetOutlineColor(); } -void Controller::SetOutlineWidth( float width ) +void Controller::SetOutlineWidth( unsigned int width ) { mImpl->mModel->mVisualModel->SetOutlineWidth( width ); mImpl->RequestRelayout(); } -float Controller::GetOutlineWidth() const +unsigned int Controller::GetOutlineWidth() const { return mImpl->mModel->mVisualModel->GetOutlineWidth(); } diff --git a/dali-toolkit/internal/text/text-controller.h b/dali-toolkit/internal/text/text-controller.h index 07d91be..88831db 100755 --- a/dali-toolkit/internal/text/text-controller.h +++ b/dali-toolkit/internal/text/text-controller.h @@ -834,14 +834,14 @@ public: // Default style & Input style * * @param[in] width The width in pixels of the outline, 0 indicates no outline */ - void SetOutlineWidth( float width ); + void SetOutlineWidth( unsigned int width ); /** * @brief Retrieves the width of an outline * * @return The width of the outline. */ - float GetOutlineWidth() const; + unsigned int GetOutlineWidth() const; /** * @brief Sets the emboss's properties string. diff --git a/dali-toolkit/internal/text/text-effects-style.cpp b/dali-toolkit/internal/text/text-effects-style.cpp index 7c08ebe..e56eac3 100755 --- a/dali-toolkit/internal/text/text-effects-style.cpp +++ b/dali-toolkit/internal/text/text-effects-style.cpp @@ -125,26 +125,45 @@ bool ParseUnderlineProperties( const Property::Map& underlinePropertiesMap, if( ENABLE_KEY == valueGet.first.stringKey ) { /// Enable key. - const std::string enableStr = valueGet.second.Get(); - enabled = Text::TokenComparison( TRUE_TOKEN, enableStr.c_str(), enableStr.size() ); + if( valueGet.second.GetType() == Dali::Property::STRING ) + { + const std::string enableStr = valueGet.second.Get(); + enabled = Text::TokenComparison( TRUE_TOKEN, enableStr.c_str(), enableStr.size() ); + } + else + { + enabled = valueGet.second.Get(); + } } else if( COLOR_KEY == valueGet.first.stringKey ) { /// Color key. colorDefined = true; - const std::string colorStr = valueGet.second.Get(); - - Text::ColorStringToVector4( colorStr.c_str(), colorStr.size(), color ); + if( valueGet.second.GetType() == Dali::Property::STRING ) + { + const std::string colorStr = valueGet.second.Get(); + Text::ColorStringToVector4( colorStr.c_str(), colorStr.size(), color ); + } + else + { + color = valueGet.second.Get(); + } } else if( HEIGHT_KEY == valueGet.first.stringKey ) { /// Height key. heightDefined = true; - const std::string heightStr = valueGet.second.Get(); - - height = StringToFloat( heightStr.c_str() ); + if( valueGet.second.GetType() == Dali::Property::STRING ) + { + const std::string heightStr = valueGet.second.Get(); + height = StringToFloat( heightStr.c_str() ); + } + else + { + height = valueGet.second.Get(); + } } } @@ -155,7 +174,7 @@ bool ParseOutlineProperties( const Property::Map& underlinePropertiesMap, bool& colorDefined, Vector4& color, bool& widthDefined, - float& width ) + unsigned int& width ) { const unsigned int numberOfItems = underlinePropertiesMap.Count(); @@ -174,7 +193,7 @@ bool ParseOutlineProperties( const Property::Map& underlinePropertiesMap, { /// Width key. widthDefined = true; - width = valueGet.second.Get(); + width = static_cast( valueGet.second.Get() ); } } @@ -218,7 +237,7 @@ bool SetUnderlineProperties( ControllerPtr controller, const Property::Value& va heightDefined, height ); - controller->UnderlineSetByString( !empty); + controller->UnderlineSetByString( !empty ); } } else @@ -546,7 +565,7 @@ bool SetOutlineProperties( ControllerPtr controller, const Property::Value& valu bool colorDefined = false; Vector4 color; bool widthDefined = false; - float width = 0.f; + unsigned int width = 0u; bool empty = true; @@ -581,7 +600,7 @@ bool SetOutlineProperties( ControllerPtr controller, const Property::Value& valu update = true; } - if( widthDefined && ( fabsf( controller->GetOutlineWidth() - width ) > Math::MACHINE_EPSILON_1000 ) ) + if( widthDefined && ( controller->GetOutlineWidth() != width ) ) { controller->SetOutlineWidth( width ); update = true; @@ -590,9 +609,9 @@ bool SetOutlineProperties( ControllerPtr controller, const Property::Value& valu else { // Disable outline - if( fabsf( controller->GetOutlineWidth() ) > Math::MACHINE_EPSILON_1000 ) + if( 0u != controller->GetOutlineWidth() ) { - controller->SetOutlineWidth( 0.0f ); + controller->SetOutlineWidth( 0u ); update = true; } } @@ -627,7 +646,7 @@ void GetOutlineProperties( ControllerPtr controller, Property::Value& value, Eff else { const Vector4& color = controller->GetOutlineColor(); - const float width = controller->GetOutlineWidth(); + const unsigned int width = controller->GetOutlineWidth(); Property::Map map; @@ -636,7 +655,7 @@ void GetOutlineProperties( ControllerPtr controller, Property::Value& value, Eff map.Insert( COLOR_KEY, colorStr ); std::string widthStr; - FloatToString( width, widthStr ); + UintToString( width, widthStr ); map.Insert( WIDTH_KEY, widthStr ); value = map; diff --git a/dali-toolkit/internal/text/text-effects-style.h b/dali-toolkit/internal/text/text-effects-style.h index 521f52c..e2b0f0c 100755 --- a/dali-toolkit/internal/text/text-effects-style.h +++ b/dali-toolkit/internal/text/text-effects-style.h @@ -84,7 +84,7 @@ bool ParseOutlineProperties( const Property::Map& outlineProperties, bool& colorDefined, Vector4& color, bool& widthDefined, - float& width ); + unsigned int& width ); /** * @brief Sets the underline properties. diff --git a/dali-toolkit/internal/text/text-view-interface.h b/dali-toolkit/internal/text/text-view-interface.h index efa88ad..96f9005 100644 --- a/dali-toolkit/internal/text/text-view-interface.h +++ b/dali-toolkit/internal/text/text-view-interface.h @@ -172,6 +172,21 @@ public: virtual void GetUnderlineRuns( GlyphRun* underlineRuns, UnderlineRunIndex index, Length numberOfRuns ) const = 0; + + /** + * @brief Retrieve the outline color. + * + * @return The outline color. + */ + virtual const Vector4& GetOutlineColor() const = 0; + + /** + * @brief Retrieves the width of an outline + * + * @return The width of the outline. + */ + virtual unsigned int GetOutlineWidth() const = 0; + }; } // namespace Text diff --git a/dali-toolkit/internal/text/text-view.cpp b/dali-toolkit/internal/text/text-view.cpp index 9e8d0be..62c0008 100644 --- a/dali-toolkit/internal/text/text-view.cpp +++ b/dali-toolkit/internal/text/text-view.cpp @@ -402,6 +402,24 @@ void View::GetUnderlineRuns( GlyphRun* underlineRuns, } } +const Vector4& View::GetOutlineColor() const +{ + if( mImpl->mVisualModel ) + { + return mImpl->mVisualModel->GetOutlineColor(); + } + return Vector4::ZERO; +} + +unsigned int View::GetOutlineWidth() const +{ + if( mImpl->mVisualModel ) + { + return mImpl->mVisualModel->GetOutlineWidth(); + } + return 0u; +} + } // namespace Text } // namespace Toolkit diff --git a/dali-toolkit/internal/text/text-view.h b/dali-toolkit/internal/text/text-view.h index d494d2b..51426de 100644 --- a/dali-toolkit/internal/text/text-view.h +++ b/dali-toolkit/internal/text/text-view.h @@ -131,6 +131,16 @@ public: UnderlineRunIndex index, Length numberOfRuns ) const; + /** + * @copydoc Dali::Toolkit::Text::ViewInterface::GetOutlineColor() + */ + virtual const Vector4& GetOutlineColor() const; + + /** + * @copydoc Dali::Toolkit::Text::ViewInterface::GetOutlineWidth() + */ + virtual unsigned int GetOutlineWidth() const; + private: // Undefined diff --git a/dali-toolkit/internal/text/visual-model-impl.cpp b/dali-toolkit/internal/text/visual-model-impl.cpp index 9caa523..5373a6a 100755 --- a/dali-toolkit/internal/text/visual-model-impl.cpp +++ b/dali-toolkit/internal/text/visual-model-impl.cpp @@ -370,7 +370,7 @@ void VisualModel::SetUnderlineHeight( float height ) mUnderlineHeight = height; } -void VisualModel::SetOutlineWidth( float width ) +void VisualModel::SetOutlineWidth( unsigned int width ) { mOutlineWidth = width; } @@ -415,7 +415,7 @@ float VisualModel::GetUnderlineHeight() const return mUnderlineHeight; } -float VisualModel::GetOutlineWidth() const +unsigned int VisualModel::GetOutlineWidth() const { return mOutlineWidth; } @@ -449,7 +449,7 @@ VisualModel::VisualModel() mControlSize(), mShadowOffset(), mUnderlineHeight( 0.0f ), - mOutlineWidth( 0.0f ), + mOutlineWidth( 0u ), mShadowBlurRadius( 0.0f ), mNaturalSize(), mLayoutSize(), diff --git a/dali-toolkit/internal/text/visual-model-impl.h b/dali-toolkit/internal/text/visual-model-impl.h index 28d2269..24be0c7 100755 --- a/dali-toolkit/internal/text/visual-model-impl.h +++ b/dali-toolkit/internal/text/visual-model-impl.h @@ -320,14 +320,14 @@ public: * * @param[in] width The width in pixels of the outline, 0 indicates no outline */ - void SetOutlineWidth( float width ); + void SetOutlineWidth( unsigned int width ); /** * @brief Retrieves the width of an outline * * @return The width of the outline. */ - float GetOutlineWidth() const; + unsigned int GetOutlineWidth() const; protected: @@ -369,7 +369,7 @@ public: Size mControlSize; ///< The size of the UI control. Vector2 mShadowOffset; ///< Offset for drop shadow, 0 indicates no shadow float mUnderlineHeight; ///< Fixed height for underline to override font metrics. - float mOutlineWidth; ///< Width of outline. + unsigned int mOutlineWidth; ///< Width of outline. float mShadowBlurRadius; ///< Blur radius of shadow, 0 indicates no blur. private: