From: HyunJu Shin Date: Mon, 11 Sep 2017 06:01:10 +0000 (+0000) Subject: Merge "Adjust point size for 1920x1080" into devel/master X-Git-Tag: dali_1.2.57~7 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=7b08f72b7f2a1b7467f9e3fd814fb415ecbc9657;hp=74bf862a57622964da1f378906c3cc9ef4aed989 Merge "Adjust point size for 1920x1080" into devel/master --- diff --git a/automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp b/automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp index beba3a6..1a642dd 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp @@ -986,7 +986,6 @@ int UtcDaliToolkitTextLabelColorComponents(void) label.SetProperty( DevelTextLabel::Property::TEXT_COLOR_ALPHA, 0.6f ); DALI_TEST_EQUALS( label.GetProperty< float >( DevelTextLabel::Property::TEXT_COLOR_ALPHA ), 0.6f, TEST_LOCATION ); DALI_TEST_EQUALS( label.GetProperty< Vector4 >( DevelTextLabel::Property::TEXT_COLOR_ANIMATABLE ), Vector4( 0.0f, 0.0f, 1.0f, 0.6f ), TEST_LOCATION ); - DALI_TEST_EQUALS( label.GetProperty< Vector4 >( TextLabel::Property::TEXT_COLOR ), Vector4( 0.0f, 0.0f, 1.0f, 0.6f ), TEST_LOCATION ); END_TEST; } diff --git a/dali-toolkit/devel-api/visuals/text-visual-properties.h b/dali-toolkit/devel-api/visuals/text-visual-properties.h index 4286c38..10adcbc 100644 --- a/dali-toolkit/devel-api/visuals/text-visual-properties.h +++ b/dali-toolkit/devel-api/visuals/text-visual-properties.h @@ -88,18 +88,6 @@ enum * @details name "enableMarkup", type BOOLEAN */ ENABLE_MARKUP, - - /** - * @brief The shadow parameters. - * @details name "shadow", type MAP. - */ - SHADOW, - - /** - * @brief The default underline parameters. - * @details name "underline", type MAP. - */ - UNDERLINE, }; } // namespace Property diff --git a/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp index d92b1cd..db99cc4 100644 --- a/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp @@ -35,13 +35,6 @@ #include #include -#include -#include -#include -#include -#include -#include - using namespace Dali::Toolkit::Text; namespace Dali @@ -104,7 +97,7 @@ BaseHandle Create() // Setup properties, signals and actions using the type-registry. DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TextLabel, Toolkit::Control, Create ); -DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "renderingBackend", INTEGER, RENDERING_BACKEND ) // Deprecated property +DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "renderingBackend", INTEGER, RENDERING_BACKEND ) DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "text", STRING, TEXT ) DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "fontFamily", STRING, FONT_FAMILY ) DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "fontStyle", MAP, FONT_STYLE ) @@ -134,7 +127,7 @@ DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextLabel, "autoScrollLoopDelay", FLO DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextLabel, "autoScrollStopMode", STRING, AUTO_SCROLL_STOP_MODE ) DALI_DEVEL_PROPERTY_REGISTRATION_READ_ONLY( Toolkit, TextLabel, "lineCount", INTEGER, LINE_COUNT ) DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextLabel, "lineWrapMode", STRING, LINE_WRAP_MODE ) -DALI_DEVEL_ANIMATABLE_PROPERTY_REGISTRATION_WITH_DEFAULT( Toolkit, TextLabel, "textColorAnimatable", Color::BLACK, TEXT_COLOR_ANIMATABLE ) +DALI_DEVEL_ANIMATABLE_PROPERTY_REGISTRATION_WITH_DEFAULT( Toolkit, TextLabel, "textColorAnimatable", Color::WHITE, TEXT_COLOR_ANIMATABLE ) DALI_DEVEL_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit, TextLabel, "textColorRed", TEXT_COLOR_RED, TEXT_COLOR_ANIMATABLE, 0) DALI_DEVEL_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit, TextLabel, "textColorGreen", TEXT_COLOR_GREEN, TEXT_COLOR_ANIMATABLE, 1) DALI_DEVEL_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit, TextLabel, "textColorBlue", TEXT_COLOR_BLUE, TEXT_COLOR_ANIMATABLE, 2) @@ -169,8 +162,6 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr { case Toolkit::TextLabel::Property::RENDERING_BACKEND: { - DALI_LOG_WARNING("[%s] Using deprecated Property TextLabel::Property::RENDERING_BACKEND which is no longer supported and will be ignored\n", __FUNCTION__); - int backend = value.Get< int >(); #ifndef ENABLE_VECTOR_BASED_TEXT_RENDERING @@ -182,7 +173,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr if( impl.mRenderingBackend != backend ) { impl.mRenderingBackend = backend; - impl.mTextUpdateNeeded = true; + impl.mRenderer.Reset(); if( impl.mController ) { @@ -271,8 +262,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr case Toolkit::TextLabel::Property::TEXT_COLOR: { - label.SetProperty( DevelTextLabel::Property::TEXT_COLOR_ANIMATABLE, value ); - impl.mTextUpdateNeeded = true; + SetProperty( object, DevelTextLabel::Property::TEXT_COLOR_ANIMATABLE, value ); break; } @@ -284,7 +274,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr if ( impl.mController->GetShadowOffset() != shadowOffset ) { impl.mController->SetShadowOffset( shadowOffset ); - impl.mTextUpdateNeeded = true; + impl.mRenderer.Reset(); } } break; @@ -297,7 +287,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr if ( impl.mController->GetShadowColor() != shadowColor ) { impl.mController->SetShadowColor( shadowColor ); - impl.mTextUpdateNeeded = true; + impl.mRenderer.Reset(); } } break; @@ -310,7 +300,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr if ( impl.mController->GetUnderlineColor() != color ) { impl.mController->SetUnderlineColor( color ); - impl.mTextUpdateNeeded = true; + impl.mRenderer.Reset(); } } break; @@ -323,7 +313,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr if ( impl.mController->IsUnderlineEnabled() != enabled ) { impl.mController->SetUnderlineEnabled( enabled ); - impl.mTextUpdateNeeded = true; + impl.mRenderer.Reset(); } } break; @@ -337,7 +327,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr if( fabsf( impl.mController->GetUnderlineHeight() - height ) > Math::MACHINE_EPSILON_1000 ) { impl.mController->SetUnderlineHeight( height ); - impl.mTextUpdateNeeded = true; + impl.mRenderer.Reset(); } } break; @@ -435,7 +425,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr { const float lineSpacing = value.Get(); impl.mController->SetDefaultLineSpacing( lineSpacing ); - impl.mTextUpdateNeeded = true; + impl.mRenderer.Reset(); } break; } @@ -444,7 +434,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr const bool update = SetUnderlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT ); if( update ) { - impl.mTextUpdateNeeded = true; + impl.mRenderer.Reset(); } break; } @@ -453,7 +443,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr const bool update = SetShadowProperties( impl.mController, value, Text::EffectStyle::DEFAULT ); if( update ) { - impl.mTextUpdateNeeded = true; + impl.mRenderer.Reset(); } break; } @@ -462,7 +452,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr const bool update = SetEmbossProperties( impl.mController, value, Text::EffectStyle::DEFAULT ); if( update ) { - impl.mTextUpdateNeeded = true; + impl.mRenderer.Reset(); } break; } @@ -471,7 +461,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr const bool update = SetOutlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT ); if( update ) { - impl.mTextUpdateNeeded = true; + impl.mRenderer.Reset(); } break; } @@ -532,8 +522,6 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde { case Toolkit::TextLabel::Property::RENDERING_BACKEND: { - DALI_LOG_WARNING("[%s] Using deprecated Property TextLabel::Property::RENDERING_BACKEND which is no longer supported and will be ignored\n", __FUNCTION__); - value = impl.mRenderingBackend; break; } @@ -606,7 +594,10 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde } case Toolkit::TextLabel::Property::TEXT_COLOR: { - value = label.GetProperty( Toolkit::DevelTextLabel::Property::TEXT_COLOR_ANIMATABLE ); + if( impl.mController ) + { + value = impl.mController->GetDefaultColor(); + } break; } case Toolkit::TextLabel::Property::SHADOW_OFFSET: @@ -792,19 +783,11 @@ void TextLabel::OnInitialize() { Actor self = Self(); - Property::Map propertyMap; - propertyMap.Add( Toolkit::Visual::Property::TYPE, Toolkit::DevelVisual::TEXT ); + mController = Text::Controller::New( this ); - mVisual = Toolkit::VisualFactory::Get().CreateVisual( propertyMap ); - DevelControl::RegisterVisual( *this, Toolkit::TextLabel::Property::TEXT, mVisual ); - - TextVisual::SetAnimatableTextColorProperty( mVisual, Toolkit::DevelTextLabel::Property::TEXT_COLOR_ANIMATABLE ); - - mController = TextVisual::GetController(mVisual); - if( mController ) - { - mController->SetControlInterface(this); - } + // When using the vector-based rendering, the size of the GLyphs are different + TextAbstraction::GlyphType glyphType = (Text::RENDERING_VECTOR_BASED == mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH; + mController->SetGlyphType( glyphType ); // Use height-for-width negotiation by default self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH ); @@ -815,6 +798,8 @@ void TextLabel::OnInitialize() Layout::Engine& engine = mController->GetLayoutEngine(); engine.SetCursorWidth( 0u ); // Do not layout space for the cursor. + + self.OnStageSignal().Connect( this, &TextLabel::OnStageConnect ); } void TextLabel::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change ) @@ -867,13 +852,14 @@ void TextLabel::OnPropertySet( Property::Index index, Property::Value propertyVa switch ( index ) { + case Toolkit::TextLabel::Property::TEXT_COLOR: case Toolkit::DevelTextLabel::Property::TEXT_COLOR_ANIMATABLE: { const Vector4& textColor = propertyValue.Get< Vector4 >(); if( mController->GetDefaultColor() != textColor ) { mController->SetDefaultColor( textColor ); - mTextUpdateNeeded = true; + mRenderer.Reset(); } break; } @@ -893,50 +879,76 @@ void TextLabel::OnRelayout( const Vector2& size, RelayoutContainer& container ) Self().GetPadding( padding ); Vector2 contentSize( size.x - ( padding.left + padding.right ), size.y - ( padding.top + padding.bottom ) ); + const Text::Controller::UpdateTextType updateTextType = mController->Relayout( contentSize ); - if( ( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType ) ) - || mTextUpdateNeeded ) + if( ( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType ) ) || + !mRenderer ) { - DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::OnRelayout IsAutoScrollEnabled[%s] [%p]\n", ( mController->IsAutoScrollEnabled())?"true":"false", this ); + if( !mRenderer ) + { + mRenderer = Text::Backend::Get().NewRenderer( mRenderingBackend ); + } + RenderText(); + } +} + +void TextLabel::RequestTextRelayout() +{ + RelayoutRequest(); +} - // Update the visual - TextVisual::EnableRendererUpdate( mVisual ); +void TextLabel::RenderText() +{ + DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::RenderText IsAutoScrollEnabled[%s] [%p]\n", ( mController->IsAutoScrollEnabled())?"true":"false", this ); - Padding padding; - Self().GetPadding( padding ); + Actor self = Self(); + Actor renderableActor; - Property::Map visualTransform; - visualTransform.Add( Toolkit::DevelVisual::Transform::Property::SIZE, contentSize ) - .Add( Toolkit::DevelVisual::Transform::Property::SIZE_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) ) - .Add( Toolkit::DevelVisual::Transform::Property::OFFSET, Vector2(padding.left, padding.top) ) - .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_POLICY, Vector2( Toolkit::DevelVisual::Transform::Policy::ABSOLUTE, Toolkit::DevelVisual::Transform::Policy::ABSOLUTE ) ) - .Add( Toolkit::DevelVisual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN ) - .Add( Toolkit::DevelVisual::Transform::Property::ANCHOR_POINT, Toolkit::Align::TOP_BEGIN ); - mVisual.SetTransformAndSize( visualTransform, size ); + float alignmentOffset = 0.f; + if( mRenderer ) + { + + Dali::Toolkit::TextLabel handle = Dali::Toolkit::TextLabel( GetOwner() ); + + renderableActor = mRenderer->Render( mController->GetView(), + handle, + Toolkit::DevelTextLabel::Property::TEXT_COLOR_ANIMATABLE, + alignmentOffset, + DepthIndex::CONTENT ); + } + + if( renderableActor != mRenderableActor ) + { + UnparentAndReset( mRenderableActor ); + + if( renderableActor ) + { + const Vector2& scrollOffset = mController->GetTextModel()->GetScrollPosition(); + Padding padding; + self.GetPadding( padding ); + renderableActor.SetPosition( scrollOffset.x + alignmentOffset + padding.left, scrollOffset.y + padding.top ); + + self.Add( renderableActor ); + } + mRenderableActor = renderableActor; if ( mController->IsAutoScrollEnabled() ) { SetUpAutoScrolling(); } - - mTextUpdateNeeded = false; } } -void TextLabel::RequestTextRelayout() -{ - RelayoutRequest(); -} - void TextLabel::SetUpAutoScrolling() { const Size& controlSize = mController->GetView().GetControlSize(); - const Size textNaturalSize = GetNaturalSize().GetVectorXY(); // As relayout of text may not be done at this point natural size is used to get size. Single line scrolling only. + const Size offScreenSize = GetNaturalSize().GetVectorXY(); // As relayout of text may not be done at this point natural size is used to get size. Single line scrolling only. + const float alignmentOffset = mController->GetAutoScrollLineAlignment(); const Text::CharacterDirection direction = mController->GetAutoScrollDirection(); - DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::SetUpAutoScrolling textNaturalSize[%f,%f] controlSize[%f,%f]\n", - textNaturalSize.x,textNaturalSize.y , controlSize.x,controlSize.y ); + DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::SetUpAutoScrolling alignmentOffset[%f] offScreenSize[%f,%f] controlSize[%f,%f]\n", + alignmentOffset, offScreenSize.x,offScreenSize.y , controlSize.x,controlSize.y ); if ( !mTextScroller ) { @@ -945,27 +957,23 @@ void TextLabel::SetUpAutoScrolling() // If speed, loopCount or gap not set via property system then will need to create a TextScroller with defaults mTextScroller = Text::TextScroller::New( *this ); } + mTextScroller->SetParameters( mRenderableActor, controlSize, offScreenSize, direction, alignmentOffset, mController->GetHorizontalAlignment() ); + + Actor self = Self(); + self.Add( mTextScroller->GetScrollingText() ); + self.Add( mTextScroller->GetSourceCamera() ); +} - // Create a texture of the text for scrolling - Text::TypesetterPtr typesetter = Text::Typesetter::New( mController->GetTextModel() ); - PixelData data = typesetter->Render( textNaturalSize, Text::Typesetter::RENDER_TEXT_AND_STYLES, true ); // ignore the horizontal alignment - Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D, - data.GetPixelFormat(), - data.GetWidth(), - data.GetHeight() ); - texture.Upload( data ); - - TextureSet textureSet = TextureSet::New(); - textureSet.SetTexture( 0u, texture ); - - // Filter mode needs to be set to linear to produce better quality while scaling. - Sampler sampler = Sampler::New(); - sampler.SetFilterMode( FilterMode::LINEAR, FilterMode::LINEAR ); - textureSet.SetSampler( 0u, sampler ); - - // Set parameters for scrolling - Renderer renderer = static_cast( GetImplementation( mVisual ) ).GetRenderer(); - mTextScroller->SetParameters( Self(), renderer, textureSet, controlSize, textNaturalSize, direction, mController->GetHorizontalAlignment(), mController->GetVerticalAlignment() ); +void TextLabel::OnStageConnect( Dali::Actor actor ) +{ + if ( mHasBeenStaged ) + { + RenderText(); + } + else + { + mHasBeenStaged = true; + } } void TextLabel::ScrollingFinished() @@ -980,7 +988,7 @@ void TextLabel::ScrollingFinished() TextLabel::TextLabel() : Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ), mRenderingBackend( DEFAULT_RENDERING_BACKEND ), - mTextUpdateNeeded( false ) + mHasBeenStaged( false ) { } diff --git a/dali-toolkit/internal/controls/text-controls/text-label-impl.h b/dali-toolkit/internal/controls/text-controls/text-label-impl.h index 85e94ab..f15acbf 100644 --- a/dali-toolkit/internal/controls/text-controls/text-label-impl.h +++ b/dali-toolkit/internal/controls/text-controls/text-label-impl.h @@ -18,9 +18,6 @@ * */ -// EXTERNAL INCLUDES -#include - // INTERNAL INCLUDES #include #include @@ -29,8 +26,6 @@ #include #include #include -#include - namespace Dali { @@ -137,6 +132,14 @@ private: TextLabel(const TextLabel&); TextLabel& operator=(const TextLabel& rhs); + // Connection needed to re-render text, when a Text Label returns to the stage + void OnStageConnect( Dali::Actor actor ); + + /** + * @brief Render view, create and attach actor(s) to this Text Label + */ + void RenderText(); + /** * @brief Set up Autoscrolling */ @@ -145,12 +148,11 @@ private: private: // Data Text::ControllerPtr mController; + Text::RendererPtr mRenderer; Text::TextScrollerPtr mTextScroller; - - Toolkit::Visual::Base mVisual; - + Actor mRenderableActor; int mRenderingBackend; - bool mTextUpdateNeeded:1; + bool mHasBeenStaged:1; }; } // namespace Internal diff --git a/dali-toolkit/internal/text/rendering/text-typesetter.cpp b/dali-toolkit/internal/text/rendering/text-typesetter.cpp index 1821db4..78aba49 100644 --- a/dali-toolkit/internal/text/rendering/text-typesetter.cpp +++ b/dali-toolkit/internal/text/rendering/text-typesetter.cpp @@ -21,7 +21,6 @@ // EXTERNAL INCLUDES #include #include -#include // INTERNAL INCLUDES #include @@ -43,7 +42,7 @@ namespace */ struct GlyphData { - Devel::PixelBuffer bitmapBuffer; ///< The buffer of the whole bitmap. The format is RGBA8888. + uint32_t* bitmapBuffer; ///< The buffer of the whole bitmap. The format is RGBA8888. Vector2* position; ///< The position of the glyph. TextAbstraction::FontClient::GlyphBufferData glyphBitmap; ///< The glyph's bitmap. unsigned int width; ///< The bitmap's width. @@ -58,12 +57,10 @@ struct GlyphData * @param[in] data Struct which contains the glyph's data and the bitmap's data. * @param[in] position The position of the glyph. * @param[in] color The color of the glyph. - * @param[in] style The style of the text. */ -void TypesetGlyph( GlyphData& data, +void TypesetGlyph( const GlyphData& data, const Vector2* const position, - const Vector4* const color, - Typesetter::Style style) + const Vector4* const color ) { if( ( 0u == data.glyphBitmap.width ) || ( 0u == data.glyphBitmap.height ) ) { @@ -113,88 +110,32 @@ void TypesetGlyph( GlyphData& data, break; } - uint32_t* bitmapBuffer = reinterpret_cast< uint32_t* >( data.bitmapBuffer.GetBuffer() ); - if( isColorGlyph ) { - // Retrieves the color from the color glyph. The format is BGRA8888. + // Retrieves the color from the glyph. The format is BGRA8888. uint32_t packedColorGlyph = *( colorGlyphBuffer + glyphBufferOffset + index ); - uint8_t* packedColorGlyphBuffer = reinterpret_cast( &packedColorGlyph ); - - if( Typesetter::STYLE_SHADOW == style ) - { - // The shadow of color glyph needs to have the shadow color. - *( packedColorGlyphBuffer + 2 ) = static_cast( color->b * 255.f ); - *( packedColorGlyphBuffer + 1 ) = static_cast( color->g * 255.f ); - *packedColorGlyphBuffer = static_cast( color->r * 255.f ); - } - else - { - std::swap( *packedColorGlyphBuffer, *( packedColorGlyphBuffer + 2u ) ); // Swap B and R. - } // Update the alpha channel. - if( Typesetter::STYLE_MASK == style ) - { - // Create an alpha mask for color glyph. - *( packedColorGlyphBuffer + 3u ) = 0u; - } - else - { - *( packedColorGlyphBuffer + 3u ) = static_cast( color->a * static_cast( *( packedColorGlyphBuffer + 3u ) ) ); - } + uint8_t* packedColorGlyphBuffer = reinterpret_cast( &packedColorGlyph ); + std::swap( *packedColorGlyphBuffer, *( packedColorGlyphBuffer + 2u ) ); // Swap B and R. + *( packedColorGlyphBuffer + 3u ) = static_cast( color->a * static_cast( *( packedColorGlyphBuffer + 3u ) ) ); // Set the color into the final pixel buffer. - *( bitmapBuffer + verticalOffset + xOffsetIndex ) = packedColorGlyph; + *( data.bitmapBuffer + verticalOffset + xOffsetIndex ) = packedColorGlyph; } else { // Update the alpha channel. const uint8_t alpha = *( data.glyphBitmap.buffer + glyphBufferOffset + index ); + *( packedColorBuffer + 3u ) = static_cast( color->a * static_cast( alpha ) ); - // Copy non-transparent pixels only - if ( alpha > 0u ) - { - // Check alpha of overlapped pixels - uint32_t& currentColor = *( bitmapBuffer + verticalOffset + xOffsetIndex ); - uint8_t* packedCurrentColorBuffer = reinterpret_cast( ¤tColor ); - - uint8_t currentAlpha = *( packedCurrentColorBuffer + 3u ); - uint8_t newAlpha = static_cast( color->a * static_cast( alpha ) ); - - // For any pixel overlapped with the pixel in previous glyphs, make sure we don't - // overwrite a previous bigger alpha with a smaller alpha (in order to avoid - // semi-transparent gaps between joint glyphs with overlapped pixels, which could - // happen, for example, in the RTL text when we copy glyphs from right to left). - *( packedColorBuffer + 3u ) = std::max( currentAlpha, newAlpha ); - - // Set the color into the final pixel buffer. - currentColor = packedColor; - } + // Set the color into the final pixel buffer. + *( data.bitmapBuffer + verticalOffset + xOffsetIndex ) = packedColor; } } } } -bool IsGlyphUnderlined( GlyphIndex index, - const Vector& underlineRuns ) -{ - 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; -} - } // namespace TypesetterPtr Typesetter::New( const ModelInterface* const model ) @@ -207,7 +148,7 @@ ViewModel* Typesetter::GetViewModel() return mModel; } -PixelData Typesetter::Render( const Vector2& size, RenderBehaviour behaviour, bool ignoreHorizontalAlignment ) +PixelData Typesetter::Render( const Vector2& size ) { // @todo. This initial implementation for a TextLabel has only one visible page. @@ -239,73 +180,6 @@ PixelData Typesetter::Render( const Vector2& size, RenderBehaviour behaviour, bo } } - // Generate the image buffers of the text for each different style first, - // then combine all of them together as one final image buffer. We try to - // do all of these in CPU only, so that once the final texture is generated, - // no calculation is needed in GPU during each frame. - - const unsigned int bufferWidth = static_cast( size.width ); - const unsigned int bufferHeight = static_cast( size.height ); - - const unsigned int bufferSizeInt = bufferWidth * bufferHeight; - const unsigned int bufferSizeChar = 4u * bufferSizeInt; - - Length numberOfGlyphs = mModel->GetNumberOfGlyphs(); - - Devel::PixelBuffer imageBuffer; - - if( RENDER_MASK == behaviour ) - { - // Generate the image buffer as an alpha mask for color glyphs. - imageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_MASK, ignoreHorizontalAlignment, penY, 0u, numberOfGlyphs - 1 ); - } - else if( RENDER_NO_TEXT == behaviour ) - { - // Generate an empty image buffer so that it can been combined with the image buffers for styles - imageBuffer = Devel::PixelBuffer::New( bufferWidth, bufferHeight, Pixel::RGBA8888 ); - memset( imageBuffer.GetBuffer(), 0u, bufferSizeChar ); - } - else - { - // Generate the image buffer for the text with no style. - imageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_NONE, ignoreHorizontalAlignment, penY, 0u, numberOfGlyphs -1 ); - } - - if ( ( RENDER_NO_STYLES != behaviour ) && ( RENDER_MASK != behaviour ) ) - { - // @todo. Support shadow and underline for partial text later on. - - // Generate the shadow if enabled - const Vector2& shadowOffset = mModel->GetShadowOffset(); - if ( fabsf( shadowOffset.x ) > Math::MACHINE_EPSILON_1 || fabsf( shadowOffset.y ) > Math::MACHINE_EPSILON_1 ) - { - // Create the image buffer for shadow - Devel::PixelBuffer shadowImageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_SHADOW, ignoreHorizontalAlignment, penY, 0u, numberOfGlyphs - 1 ); - - // Combine the two buffers - imageBuffer = CombineImageBuffer( imageBuffer, shadowImageBuffer, bufferWidth, bufferHeight ); - } - - // Generate the underline if enabled - const bool underlineEnabled = mModel->IsUnderlineEnabled(); - if ( underlineEnabled ) - { - // Create the image buffer for underline - Devel::PixelBuffer underlineImageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_UNDERLINE, ignoreHorizontalAlignment, penY, 0u, numberOfGlyphs - 1 ); - - // Combine the two buffers - imageBuffer = CombineImageBuffer( imageBuffer, underlineImageBuffer, bufferWidth, bufferHeight ); - } - } - - // Create the final PixelData for the combined image buffer - PixelData pixelData = Devel::PixelBuffer::Convert( imageBuffer ); - - return pixelData; -} - -Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth, const unsigned int bufferHeight, Typesetter::Style style, bool ignoreHorizontalAlignment, int verticalOffset, GlyphIndex fromGlyphIndex, GlyphIndex toGlyphIndex ) -{ // Retrieve lines, glyphs, positions and colors from the view model. const Length modelNumberOfLines = mModel->GetNumberOfLines(); const LineRun* const modelLinesBuffer = mModel->GetLines(); @@ -316,19 +190,26 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth const ColorIndex* const colorIndexBuffer = mModel->GetColorIndices(); // Whether to use the default color. - const bool useDefaultColor = ( NULL == colorsBuffer ); + const bool useDefaultColor = NULL == colorsBuffer; const Vector4& defaultColor = mModel->GetDefaultColor(); // Create and initialize the pixel buffer. GlyphData glyphData; - glyphData.verticalOffset = verticalOffset; + glyphData.verticalOffset = penY; - glyphData.width = bufferWidth; - glyphData.height = bufferHeight; - const unsigned int bufferSizeInt = bufferWidth * bufferHeight; + glyphData.width = static_cast( size.width ); + glyphData.height = static_cast( size.height ); + const unsigned int bufferSizeInt = glyphData.width * glyphData.height; const unsigned int bufferSizeChar = 4u * bufferSizeInt; - glyphData.bitmapBuffer = Devel::PixelBuffer::New( bufferWidth, bufferHeight, Pixel::RGBA8888 ); - memset( glyphData.bitmapBuffer.GetBuffer(), 0u, bufferSizeChar ); + glyphData.bitmapBuffer = new uint32_t[ bufferSizeInt ]; // This array will get deleted by PixelData because of the DELETE_ARRAY parameter. + memset( glyphData.bitmapBuffer, 0u, bufferSizeChar ); + + PixelData pixelData = PixelData::New( reinterpret_cast( glyphData.bitmapBuffer ), + bufferSizeChar, + glyphData.width, + glyphData.height, + Pixel::RGBA8888, // The format is RGBA8888 because is the format accepted by the image atlas manager. + PixelData::DELETE_ARRAY ); // Get a handle of the font client. Used to retrieve the bitmaps of the glyphs. TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get(); @@ -339,54 +220,15 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth const LineRun& line = *( modelLinesBuffer + lineIndex ); // Sets the horizontal offset of the line. - glyphData.horizontalOffset = ignoreHorizontalAlignment ? 0 : static_cast( line.alignmentOffset ); + glyphData.horizontalOffset = static_cast( line.alignmentOffset ); // Increases the vertical offset with the line's ascender. glyphData.verticalOffset += static_cast( line.ascender ); - if ( style == Typesetter::STYLE_SHADOW ) - { - const Vector2& shadowOffset = mModel->GetShadowOffset(); - glyphData.horizontalOffset += shadowOffset.x; - if ( lineIndex == 0u ) - { - // Only need to add the vertical shadow offset for once - glyphData.verticalOffset += shadowOffset.y; - } - } - - const bool underlineEnabled = mModel->IsUnderlineEnabled(); - const Vector4& underlineColor = mModel->GetUnderlineColor(); - const float underlineHeight = mModel->GetUnderlineHeight(); - - // Get the underline runs. - const Length numberOfUnderlineRuns = mModel->GetNumberOfUnderlineRuns(); - Vector underlineRuns; - underlineRuns.Resize( numberOfUnderlineRuns ); - mModel->GetUnderlineRuns( underlineRuns.Begin(), 0u, numberOfUnderlineRuns ); - - bool thereAreUnderlinedGlyphs = false; - - float currentUnderlinePosition = 0.0f; - float currentUnderlineThickness = underlineHeight; - float maxUnderlineThickness = currentUnderlineThickness; - - FontId lastUnderlinedFontId = 0; - - float lineExtentLeft = bufferWidth; - float lineExtentRight = 0.0f; - float baseline = 0.0f; - // Traverses the glyphs of the line. const GlyphIndex endGlyphIndex = std::min( numberOfGlyphs, line.glyphRun.glyphIndex + line.glyphRun.numberOfGlyphs ); for( GlyphIndex glyphIndex = line.glyphRun.glyphIndex; glyphIndex < endGlyphIndex; ++glyphIndex ) { - if ( glyphIndex < fromGlyphIndex || glyphIndex > toGlyphIndex ) - { - // Ignore any glyph that out of the specified range - continue; - } - // Retrieve the glyph's info. const GlyphInfo* const glyphInfo = glyphsBuffer + glyphIndex; @@ -397,84 +239,12 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth continue; } - const bool underlineGlyph = underlineEnabled || IsGlyphUnderlined( glyphIndex, underlineRuns ); - thereAreUnderlinedGlyphs = thereAreUnderlinedGlyphs || underlineGlyph; - - // Are we still using the same fontId as previous - if( underlineGlyph && ( glyphInfo->fontId != lastUnderlinedFontId ) ) - { - // We need to fetch fresh font underline metrics - FontMetrics fontMetrics; - fontClient.GetFontMetrics( glyphInfo->fontId, fontMetrics ); - currentUnderlinePosition = ceil( fabsf( fontMetrics.underlinePosition ) ); - const float descender = ceil( fabsf( fontMetrics.descender ) ); - - if( fabsf( underlineHeight ) < Math::MACHINE_EPSILON_1000 ) - { - currentUnderlineThickness = fontMetrics.underlineThickness; - - // Ensure underline will be at least a pixel high - if ( currentUnderlineThickness < 1.0f ) - { - currentUnderlineThickness = 1.0f; - } - else - { - currentUnderlineThickness = ceil( currentUnderlineThickness ); - } - } - - // The underline thickness should be the max underline thickness of all glyphs of the line. - if ( currentUnderlineThickness > maxUnderlineThickness ) - { - maxUnderlineThickness = currentUnderlineThickness; - } - - // Clamp the underline position at the font descender and check for ( as EFL describes it ) a broken font - if( currentUnderlinePosition > descender ) - { - currentUnderlinePosition = descender; - } - - if( fabsf( currentUnderlinePosition ) < Math::MACHINE_EPSILON_1000 ) - { - // Move offset down by one ( EFL behavior ) - currentUnderlinePosition = 1.0f; - } - - lastUnderlinedFontId = glyphInfo->fontId; - } // underline - // Retrieves the glyph's position. const Vector2* const position = positionBuffer + glyphIndex; - if ( baseline < position->y + glyphInfo->yBearing ) - { - baseline = position->y + glyphInfo->yBearing; - } - - // Calculate the positions of leftmost and rightmost glyphs in the current line - if ( position->x < lineExtentLeft) - { - lineExtentLeft = position->x; - } - - if ( position->x + glyphInfo->width > lineExtentRight) - { - lineExtentRight = position->x + glyphInfo->width; - } // Retrieves the glyph's color. const ColorIndex colorIndex = *( colorIndexBuffer + glyphIndex ); - - const Vector4* color; - if ( style == Typesetter::STYLE_SHADOW ) - { - color = &( mModel->GetShadowColor() ); - } - else - { - color = ( useDefaultColor || ( 0u == colorIndex ) ) ? &defaultColor : colorsBuffer + ( colorIndex - 1u ); - } + const Vector4* const color = ( useDefaultColor || ( 0u == colorIndex ) ) ? &defaultColor : colorsBuffer + ( colorIndex - 1u ); // Retrieves the glyph's bitmap. glyphData.glyphBitmap.buffer = NULL; @@ -489,47 +259,11 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth { TypesetGlyph( glyphData, position, - color, - style ); + color ); // delete the glyphBitmap.buffer as it is now copied into glyphData.bitmapBuffer delete []glyphData.glyphBitmap.buffer; glyphData.glyphBitmap.buffer = NULL; - } - } - // Draw the underline from the leftmost glyph to the rightmost glyph - if ( thereAreUnderlinedGlyphs && style == Typesetter::STYLE_UNDERLINE ) - { - int underlineYOffset = glyphData.verticalOffset + baseline + currentUnderlinePosition; - - for( unsigned int y = underlineYOffset; y < underlineYOffset + maxUnderlineThickness; y++ ) - { - if( ( y < 0 ) || ( y > bufferHeight - 1 ) ) - { - // Do not write out of bounds. - break; - } - - for( unsigned int x = glyphData.horizontalOffset + lineExtentLeft; x <= glyphData.horizontalOffset + lineExtentRight; x++ ) - { - if( ( x < 0 ) || ( x > bufferWidth - 1 ) ) - { - // Do not write out of bounds. - break; - } - - uint32_t* bitmapBuffer = reinterpret_cast< uint32_t* >( glyphData.bitmapBuffer.GetBuffer() ); - uint32_t underlinePixel = *( bitmapBuffer + y * glyphData.width + x ); - uint8_t* underlinePixelBuffer = reinterpret_cast( &underlinePixel ); - - // Write the underline color to the pixel buffer - *( underlinePixelBuffer ) = static_cast( underlineColor.r * 255.f ); - *( underlinePixelBuffer + 1u ) = static_cast( underlineColor.g * 255.f ); - *( underlinePixelBuffer + 2u ) = static_cast( underlineColor.b * 255.f ); - *( underlinePixelBuffer + 3u ) = static_cast( underlineColor.a * 255.f ); - - *( bitmapBuffer + y * glyphData.width + x ) = underlinePixel; - } } } @@ -537,69 +271,7 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth glyphData.verticalOffset += static_cast( -line.descender ); } - return glyphData.bitmapBuffer; -} - -Devel::PixelBuffer Typesetter::CombineImageBuffer( Devel::PixelBuffer topPixelBuffer, Devel::PixelBuffer bottomPixelBuffer, const unsigned int bufferWidth, const unsigned int bufferHeight ) -{ - unsigned char* topBuffer = topPixelBuffer.GetBuffer(); - unsigned char* bottomBuffer = bottomPixelBuffer.GetBuffer(); - - Devel::PixelBuffer combinedPixelBuffer; - - if ( topBuffer == NULL && bottomBuffer == NULL ) - { - // Nothing to do if both buffers are empty. - return combinedPixelBuffer; - } - - if ( topBuffer == NULL ) - { - // Nothing to do if topBuffer is empty. - return bottomPixelBuffer; - } - - if ( bottomBuffer == NULL ) - { - // Nothing to do if bottomBuffer is empty. - return topPixelBuffer; - } - - const unsigned int bufferSizeInt = bufferWidth * bufferHeight; - const unsigned int bufferSizeChar = 4u * bufferSizeInt; - - combinedPixelBuffer = Devel::PixelBuffer::New( bufferWidth, bufferHeight, Pixel::RGBA8888 ); - uint8_t* combinedBuffer = reinterpret_cast< uint8_t* >( combinedPixelBuffer.GetBuffer() ); - memset( combinedBuffer, 0u, bufferSizeChar ); - - for (unsigned int pixelIndex = 0; pixelIndex < bufferSizeInt; pixelIndex++) - { - // If the alpha of the pixel in either buffer is not fully opaque, blend the two pixels. - // Otherwise, copy pixel from topBuffer to combinedBuffer. - - unsigned int alphaBuffer1 = topBuffer[pixelIndex*4+3]; - unsigned int alphaBuffer2 = bottomBuffer[pixelIndex*4+3]; - - if ( alphaBuffer1 != 255 || alphaBuffer2 != 255 ) - { - // At least one pixel is not fully opaque - // "Over" blend the the pixel from topBuffer with the pixel in bottomBuffer - combinedBuffer[pixelIndex*4] = ( topBuffer[pixelIndex*4] * topBuffer[pixelIndex*4+3] / 255 ) + ( bottomBuffer[pixelIndex*4] * bottomBuffer[pixelIndex*4+3] * ( 255 - topBuffer[pixelIndex*4+3] ) / ( 255*255 ) ); - combinedBuffer[pixelIndex*4+1] = ( topBuffer[pixelIndex*4+1] * topBuffer[pixelIndex*4+3] / 255 ) + ( bottomBuffer[pixelIndex*4+1] * bottomBuffer[pixelIndex*4+3] * ( 255 - topBuffer[pixelIndex*4+3] ) / ( 255*255 ) ); - combinedBuffer[pixelIndex*4+2] = ( topBuffer[pixelIndex*4+2] * topBuffer[pixelIndex*4+3] / 255 ) + ( bottomBuffer[pixelIndex*4+2] * bottomBuffer[pixelIndex*4+3] * ( 255 - topBuffer[pixelIndex*4+3] ) / ( 255*255 ) ); - combinedBuffer[pixelIndex*4+3] = topBuffer[pixelIndex*4+3] + ( bottomBuffer[pixelIndex*4+3] * ( 255 - topBuffer[pixelIndex*4+3] ) / 255 ); - } - else - { - // Copy the pixel from topBuffer to combinedBuffer - combinedBuffer[pixelIndex*4] = topBuffer[pixelIndex*4]; - combinedBuffer[pixelIndex*4+1] = topBuffer[pixelIndex*4+1]; - combinedBuffer[pixelIndex*4+2] = topBuffer[pixelIndex*4+2]; - combinedBuffer[pixelIndex*4+3] = topBuffer[pixelIndex*4+3]; - } - } - - return combinedPixelBuffer; + return pixelData; } Typesetter::Typesetter( const ModelInterface* const model ) diff --git a/dali-toolkit/internal/text/rendering/text-typesetter.h b/dali-toolkit/internal/text/rendering/text-typesetter.h index c1408cc..a5aab65 100644 --- a/dali-toolkit/internal/text/rendering/text-typesetter.h +++ b/dali-toolkit/internal/text/rendering/text-typesetter.h @@ -22,8 +22,6 @@ #include #include #include -#include -#include namespace Dali { @@ -45,33 +43,6 @@ typedef IntrusivePtr TypesetterPtr; */ class Typesetter : public RefObject { -public: - - /** - * @brief Behaviours of how to render the text. - */ - enum RenderBehaviour - { - RENDER_TEXT_AND_STYLES, ///< Render both the text and its styles - RENDER_NO_TEXT, ///< Do not render the text itself - RENDER_NO_STYLES, ///< Do not render any styles - RENDER_MASK ///< Render an alpha mask (for color glyphs with no color animation, e.g. emoji) - }; - - /** - * @brief Styles of the text. - */ - enum Style - { - STYLE_NONE, ///< No style - STYLE_MASK, ///< Alpha mask - STYLE_SHADOW, ///< Hard shadow - STYLE_SOFT_SHADOW, ///< Soft shadow - STYLE_UNDERLINE, ///< Underline - STYLE_OUTLINE, ///< Outline - STYLE_BACKGROUND ///< Text background - }; - public: // Constructor. /** * @brief Creates a Typesetter instance. @@ -97,16 +68,15 @@ public: * Does the following operations: * - Finds the visible pages needed to be rendered. * - Elide glyphs if needed. - * - Creates image buffers for diffrent text styles with the given size. - * - Combines different image buffers to create the pixel data used to generate the final image + * - Retrieves the data buffers from the text model. + * - Creates the pixel data used to generate the final image with the given size. + * - Traverse the visible glyphs, retrieve their bitmaps and compose the final pixel data. * * @param[in] size The renderer size. - * @param[in] behaviour The behaviour of how to render the text (i.e. whether to render the text only or the styles only or both). - * @param[in] ignoreHorizontalAlignment Whether to ignore the horizontal alignment (i.e. always render as if HORIZONTAL_ALIGN_BEGIN). * * @return A pixel data with the text rendered. */ - PixelData Render( const Vector2& size, RenderBehaviour behaviour = RENDER_TEXT_AND_STYLES, bool ignoreHorizontalAlignment = false ); + PixelData Render( const Vector2& size ); private: /** @@ -122,45 +92,6 @@ private: // Declared private and left undefined to avoid copies. Typesetter& operator=( const Typesetter& handle ); - /** - * @brief Create the image buffer for the given range of the glyphs in the given style. - * - * Does the following operations: - * - Retrieves the data buffers from the text model. - * - Creates the pixel data used to generate the final image with the given size. - * - Traverse the visible glyphs, retrieve their bitmaps and compose the final pixel data. - * - * @param[in] bufferWidth The width of the image buffer. - * @param[in] bufferHeight The height of the image buffer. - * @param[in] style The style of the text. - * @param[in] ignoreHorizontalAlignment Whether to ignore the horizontal alignment, not ignored by default. - * @param[in] verticalOffset The vertical offset to be added to the glyph's position. - * @param[in] fromGlyphIndex The index of the first glyph within the text to be drawn - * @param[in] toGlyphIndex The index of the last glyph within the text to be drawn - * - * @return An image buffer with the text. - */ - Devel::PixelBuffer CreateImageBuffer( const unsigned int bufferWidth, const unsigned int bufferHeight, Typesetter::Style style, bool ignoreHorizontalAlignment, int verticalOffset, TextAbstraction::GlyphIndex fromGlyphIndex, TextAbstraction::GlyphIndex toGlyphIndex ); - - /** - * @brief Combine the two image buffers together. - * - * The top layer buffer will blend over the bottom layer buffer: - * - If the pixel is not fully opaque from either buffer, it will be blended with - * the pixel from the other buffer and copied to the combined buffer. - * - If the pixels from both buffers are fully opaque, the pixels from the top layer - * buffer will be copied to the combined buffer. - * - * @param[in] topPixelBuffer The top layer buffer. - * @param[in] bottomPixelBuffer The bottom layer buffer. - * @param[in] bufferWidth The width of the image buffer. - * @param[in] bufferHeight The height of the image buffer. - * - * @return The combined image buffer with the text. - * - */ - Devel::PixelBuffer CombineImageBuffer( Devel::PixelBuffer topPixelBuffer, Devel::PixelBuffer bottomPixelBuffer, const unsigned int bufferWidth, const unsigned int bufferHeight ); - protected: /** @@ -171,7 +102,6 @@ protected: virtual ~Typesetter(); private: - ViewModel* mModel; }; diff --git a/dali-toolkit/internal/text/rendering/view-model.cpp b/dali-toolkit/internal/text/rendering/view-model.cpp index 3a0d319..eb49465 100644 --- a/dali-toolkit/internal/text/rendering/view-model.cpp +++ b/dali-toolkit/internal/text/rendering/view-model.cpp @@ -143,41 +143,6 @@ const Vector4& ViewModel::GetDefaultColor() const return mModel->GetDefaultColor(); } -const Vector2& ViewModel::GetShadowOffset() const -{ - return mModel->GetShadowOffset(); -} - -const Vector4& ViewModel::GetShadowColor() const -{ - return mModel->GetShadowColor(); -} - -const Vector4& ViewModel::GetUnderlineColor() const -{ - return mModel->GetUnderlineColor(); -} - -bool ViewModel::IsUnderlineEnabled() const -{ - return mModel->IsUnderlineEnabled(); -} - -float ViewModel::GetUnderlineHeight() const -{ - return mModel->GetUnderlineHeight(); -} - -Length ViewModel::GetNumberOfUnderlineRuns() const -{ - return mModel->GetNumberOfUnderlineRuns(); -} - -void ViewModel::GetUnderlineRuns( GlyphRun* underlineRuns, UnderlineRunIndex index, Length numberOfRuns ) const -{ - mModel->GetUnderlineRuns( underlineRuns, index, numberOfRuns ); -} - void ViewModel::ElideGlyphs() { mIsTextElided = false; diff --git a/dali-toolkit/internal/text/rendering/view-model.h b/dali-toolkit/internal/text/rendering/view-model.h index df0e32c..d178577 100644 --- a/dali-toolkit/internal/text/rendering/view-model.h +++ b/dali-toolkit/internal/text/rendering/view-model.h @@ -127,41 +127,6 @@ public: virtual const Vector4& GetDefaultColor() const; /** - * @copydoc ModelInterface::GetShadowOffset() - */ - virtual const Vector2& GetShadowOffset() const; - - /** - * @copydoc ModelInterface::GetShadowColor() - */ - virtual const Vector4& GetShadowColor() const; - - /** - * @copydoc ModelInterface::GetUnderlineColor() - */ - virtual const Vector4& GetUnderlineColor() const; - - /** - * @copydoc ModelInterface::IsUnderlineEnabled() - */ - virtual bool IsUnderlineEnabled() const; - - /** - * @copydoc ModelInterface::GetUnderlineHeight() - */ - virtual float GetUnderlineHeight() const; - - /** - * @copydoc ModelInterface::GetNumberOfUnderlineRuns() - */ - virtual Length GetNumberOfUnderlineRuns() const; - - /** - * @copydoc ModelInterface::GetUnderlineRuns() - */ - virtual void GetUnderlineRuns( GlyphRun* underlineRuns, UnderlineRunIndex index, Length numberOfRuns ) const; - - /** * @brief Does the text elide. * * It stores a copy of the visible glyphs and removes as many glyphs as needed diff --git a/dali-toolkit/internal/text/text-controller.cpp b/dali-toolkit/internal/text/text-controller.cpp index 258fea7..7875e5c 100644 --- a/dali-toolkit/internal/text/text-controller.cpp +++ b/dali-toolkit/internal/text/text-controller.cpp @@ -1757,14 +1757,14 @@ Vector3 Controller::GetNaturalSize() mImpl->UpdateModel( onlyOnceOperations ); // Layout the text for the new width. - mImpl->mOperationsPending = static_cast( mImpl->mOperationsPending | LAYOUT | REORDER ); + mImpl->mOperationsPending = static_cast( mImpl->mOperationsPending | LAYOUT ); // Store the actual control's size to restore later. const Size actualControlSize = mImpl->mModel->mVisualModel->mControlSize; DoRelayout( Size( MAX_FLOAT, MAX_FLOAT ), static_cast( onlyOnceOperations | - LAYOUT | REORDER ), + LAYOUT ), naturalSize.GetVectorXY() ); // Do not do again the only once operations. @@ -3694,11 +3694,6 @@ void Controller::ResetScrollPosition() } } -void Controller::SetControlInterface( ControlInterface* controlInterface ) -{ - mImpl->mControlInterface = controlInterface; -} - bool Controller::ShouldClearFocusOnEscape() const { return mImpl->mShouldClearFocusOnEscape; diff --git a/dali-toolkit/internal/text/text-controller.h b/dali-toolkit/internal/text/text-controller.h index 9e193c7..1f64c24 100644 --- a/dali-toolkit/internal/text/text-controller.h +++ b/dali-toolkit/internal/text/text-controller.h @@ -999,13 +999,6 @@ public: // Default style & Input style */ const std::string& GetInputOutlineProperties() const; - /** - * @brief Set the control's interface. - * - * @param[in] controlInterface The control's interface. - */ - void SetControlInterface( ControlInterface* controlInterface ); - public: // Queries & retrieves. /** diff --git a/dali-toolkit/internal/text/text-model-interface.h b/dali-toolkit/internal/text/text-model-interface.h index d84b46a..b3eb694 100644 --- a/dali-toolkit/internal/text/text-model-interface.h +++ b/dali-toolkit/internal/text/text-model-interface.h @@ -144,57 +144,6 @@ public: * @return The default color. */ virtual const Vector4& GetDefaultColor() const = 0; - - /** - * @brief Retrieves the shadow offset, 0 indicates no shadow. - * - * @return The shadow offset. - */ - virtual const Vector2& GetShadowOffset() const = 0; - - /** - * @brief Retrieves the shadow color. - * - * @return The shadow color. - */ - virtual const Vector4& GetShadowColor() const = 0; - - /** - * @brief Retrieves the underline color. - * - * @return The underline color. - */ - virtual const Vector4& GetUnderlineColor() const = 0; - - /** - * @brief Returns whether underline is enabled or not. - * - * @return The underline state. - */ - virtual bool IsUnderlineEnabled() const = 0; - - /** - * @brief Retrieves the underline height override - * - * @return Returns the override height for an underline, 0 indicates that adaptor will determine the height - */ - 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-model.cpp b/dali-toolkit/internal/text/text-model.cpp index 05cb405..95f9514 100644 --- a/dali-toolkit/internal/text/text-model.cpp +++ b/dali-toolkit/internal/text/text-model.cpp @@ -102,41 +102,6 @@ const Vector4& Model::GetDefaultColor() const return mVisualModel->mTextColor; } -const Vector2& Model::GetShadowOffset() const -{ - return mVisualModel->mShadowOffset; -} - -const Vector4& Model::GetShadowColor() const -{ - return mVisualModel->mShadowColor; -} - -const Vector4& Model::GetUnderlineColor() const -{ - return mVisualModel->GetUnderlineColor(); -} - -bool Model::IsUnderlineEnabled() const -{ - return mVisualModel->IsUnderlineEnabled(); -} - -float Model::GetUnderlineHeight() const -{ - return mVisualModel->GetUnderlineHeight(); -} - -Length Model::GetNumberOfUnderlineRuns() const -{ - return mVisualModel->GetNumberOfUnderlineRuns(); -} - -void Model::GetUnderlineRuns( GlyphRun* underlineRuns, UnderlineRunIndex index, Length numberOfRuns ) const -{ - mVisualModel->GetUnderlineRuns( underlineRuns, index, numberOfRuns ); -} - Model::Model() : mLogicalModel(), mVisualModel(), diff --git a/dali-toolkit/internal/text/text-model.h b/dali-toolkit/internal/text/text-model.h index d8b08e9..4256421 100644 --- a/dali-toolkit/internal/text/text-model.h +++ b/dali-toolkit/internal/text/text-model.h @@ -129,41 +129,6 @@ public: */ virtual const Vector4& GetDefaultColor() const; - /** - * @copydoc ModelInterface::GetShadowOffset() - */ - virtual const Vector2& GetShadowOffset() const; - - /** - * @copydoc ModelInterface::GetShadowColor() - */ - virtual const Vector4& GetShadowColor() const; - - /** - * @copydoc ModelInterface::GetUnderlineColor() - */ - virtual const Vector4& GetUnderlineColor() const; - - /** - * @copydoc ModelInterface::IsUnderlineEnabled() - */ - virtual bool IsUnderlineEnabled() const; - - /** - * @copydoc ModelInterface::GetUnderlineHeight() - */ - virtual float GetUnderlineHeight() const; - - /** - * @copydoc ModelInterface::GetNumberOfUnderlineRuns() - */ - virtual Length GetNumberOfUnderlineRuns() const; - - /** - * @copydoc ModelInterface::GetUnderlineRuns() - */ - virtual void GetUnderlineRuns( GlyphRun* underlineRuns, UnderlineRunIndex index, Length numberOfRuns ) const; - private: // Private contructors & copy operator. /** diff --git a/dali-toolkit/internal/text/text-scroller.cpp b/dali-toolkit/internal/text/text-scroller.cpp index b109661..590f919 100644 --- a/dali-toolkit/internal/text/text-scroller.cpp +++ b/dali-toolkit/internal/text/text-scroller.cpp @@ -20,6 +20,13 @@ // EXTERNAL INCLUDES #include +#include +#include +#include +#include +#include +#include +#include #include // INTERNAL INCLUDES @@ -44,41 +51,30 @@ const char* VERTEX_SHADER_SCROLL = DALI_COMPOSE_SHADER( attribute mediump vec2 aPosition;\n varying highp vec2 vTexCoord;\n varying highp float vRatio;\n - uniform mediump vec3 uSize;\n - uniform mediump float uDelta;\n - uniform mediump vec2 uTextureSize;\n - uniform mediump float uGap;\n - uniform mediump float uHorizontalAlign;\n - uniform mediump float uVerticalAlign;\n - \n uniform mediump mat4 uModelMatrix;\n uniform mediump mat4 uViewMatrix;\n uniform mediump mat4 uProjection;\n + uniform mediump vec3 uSize;\n + uniform mediump float uDelta;\n + uniform mediump vec2 uTextureSize; + uniform mediump float uGap;\n + uniform mediump float uAlign;\n \n - //Visual size and offset - uniform mediump vec2 offset;\n - uniform mediump vec2 size;\n - uniform mediump vec4 offsetSizeMode;\n - uniform mediump vec2 origin;\n - uniform mediump vec2 anchorPoint;\n - void main()\n {\n - mediump vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy );\n - mediump vec2 visualSize = mix( uSize.xy * size, size, offsetSizeMode.zw );\n - \n - mediump float smallTextPadding = max( visualSize.x - uTextureSize.x, 0. );\n - mediump float gap = max( uGap, smallTextPadding );\n - mediump float delta = floor ( uDelta ) + 0.5;\n - vTexCoord.x = ( delta + uHorizontalAlign * ( uTextureSize.x - visualSize.x ) + floor( aPosition.x * visualSize.x ) + 0.5 - gap * 0.5 ) / ( uTextureSize.x + gap ) + 0.5;\n - vTexCoord.y = ( uVerticalAlign * ( uTextureSize.y - visualSize.y ) + floor( aPosition.y * visualSize.y ) + 0.5 ) / ( uTextureSize.y ) + 0.5;\n - vRatio = uTextureSize.x / ( uTextureSize.x + gap );\n - \n - mediump vec4 vertexPosition = vec4( floor( ( aPosition + anchorPoint ) * visualSize + ( visualOffset + origin ) * uSize.xy ), 0.0, 1.0 );\n - mediump vec4 nonAlignedVertex = uViewMatrix * uModelMatrix * vertexPosition;\n - mediump vec4 pixelAlignedVertex = vec4 ( floor( nonAlignedVertex.xyz ), 1.0 );\n - \n - gl_Position = uProjection * pixelAlignedVertex;\n + {\n + highp vec4 vertexPosition = vec4(aPosition*uSize.xy, 0.0, 1.0);\n + vertexPosition = uViewMatrix * uModelMatrix * vertexPosition ;\n + vertexPosition.x = floor( vertexPosition.x ) + 0.5; + vertexPosition.y = floor( vertexPosition.y ) + 0.5; + float smallTextPadding = max(uSize.x - uTextureSize.x, 0. );\n + float gap = max( uGap, smallTextPadding );\n + float delta = floor ( uDelta ) + 0.5; + vTexCoord.x = ( delta + ( uAlign * ( uTextureSize.x - uSize.x ) ) + ( aPosition.x * uSize.x ) )/ ( uTextureSize.x + gap );\n + vTexCoord.y = ( 0.5 + floor( aPosition.y * uSize.y ) )/ ( uTextureSize.y ) ;\n + vRatio = uTextureSize.x / ( uTextureSize.x + gap );\n + gl_Position = uProjection * vertexPosition; + }\n }\n ); @@ -92,7 +88,7 @@ const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER( highp vec2 texCoord;\n texCoord.y = vTexCoord.y;\n texCoord.x = fract( vTexCoord.x ) / vRatio;\n - if ( texCoord.x > 1.0 || texCoord.y > 1.0 )\n + if ( texCoord.x > 1.0 )\n discard;\n \n gl_FragColor = texture2D( sTexture, texCoord );\n @@ -100,46 +96,146 @@ const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER( ); /** - * @brief How the text should be aligned horizontally when scrolling the text. + * @brief How the text should be aligned when scrolling the text. * - * -0.5f aligns the text to the left, 0.0f aligns the text to the center, 0.5f aligns the text to the right. - * The final alignment depends on two factors: + * 0.0f aligns the text to the left, 1.0f aligns the text to the right. + * The final alignment depends on three factors: * 1) The alignment value of the text label (Use Text::Layout::HorizontalAlignment enumerations). * 2) The text direction, i.e. whether it's LTR or RTL (0 = LTR, 1 = RTL). + * 3) Whether the text is greater than the size of the control ( 0 = Text width <= Control width, 1 = Text width > Control width ). */ -const float HORIZONTAL_ALIGNMENT_TABLE[ Text::Layout::HORIZONTAL_ALIGN_COUNT ][ 2 ] = +const float ALIGNMENT_TABLE[ Text::Layout::HORIZONTAL_ALIGN_COUNT ][ 2 ][ 2 ] = { // HORIZONTAL_ALIGN_BEGIN { - -0.5f, // LTR - 0.5f // RTL + { // LTR + 0.0f, // Text width <= Control width + 0.0f // Text width > Control width + }, + { // RTL + 1.0f, // Text width <= Control width + 1.0f // Text width > Control width + } }, // HORIZONTAL_ALIGN_CENTER { - 0.0f, // LTR - 0.0f // RTL + { // LTR + 0.5f, // Text width <= Control width + 0.0f // Text width > Control width + }, + { // RTL + 0.5f, // Text width <= Control width + 1.0f // Text width > Control width + } }, // HORIZONTAL_ALIGN_END { - 0.5f, // LTR - -0.5f // RTL + { // LTR + 1.0f, // Text width <= Control width + 0.0f // Text width > Control width + }, + { // RTL + 0.0f, // Text width <= Control width + 1.0f // Text width > Control width + } } }; /** - * @brief How the text should be aligned vertically when scrolling the text. + * @brief Create and set up a camera for the render task to use * - * -0.5f aligns the text to the top, 0.0f aligns the text to the center, 0.5f aligns the text to the bottom. - * The alignment depends on the alignment value of the text label (Use Text::Layout::VerticalAlignment enumerations). + * @param[in] sizeOfTarget size of the source camera to look at + * @param[out] offscreenCamera custom camera */ -const float VERTICAL_ALIGNMENT_TABLE[ Text::Layout::VERTICAL_ALIGN_COUNT ] = +void CreateCameraActor( const Size& sizeOfTarget, CameraActor& offscreenCamera ) { - -0.5f, // VERTICAL_ALIGN_TOP - 0.0f, // VERTICAL_ALIGN_CENTER - 0.5f // VERTICAL_ALIGN_BOTTOM -}; + offscreenCamera = CameraActor::New(); + offscreenCamera.SetOrthographicProjection( sizeOfTarget ); + offscreenCamera.SetInvertYAxis( true ); +} + +/** + * @brief Create a render task + * + * @param[in] sourceActor actor to be used as source + * @param[in] cameraActor camera looking at source + * @param[in] offscreenTarget resulting image from render task + * @param[out] renderTask render task that has been setup + */ +void CreateRenderTask( Actor sourceActor, CameraActor cameraActor , FrameBufferImage offscreenTarget, RenderTask& renderTask ) +{ + Stage stage = Stage::GetCurrent(); + RenderTaskList taskList = stage.GetRenderTaskList(); + renderTask = taskList.CreateTask(); + renderTask.SetSourceActor( sourceActor ); + renderTask.SetExclusive( true ); + renderTask.SetInputEnabled( false ); + renderTask.SetClearEnabled( true ); + renderTask.SetCameraActor( cameraActor ); + renderTask.SetTargetFrameBuffer( offscreenTarget ); + renderTask.SetClearColor( Color::TRANSPARENT ); + renderTask.SetCullMode( false ); +} + +/** + * @brief Create quad geometry for the mesh + * + * @param[out] geometry quad geometry that can be used for a mesh + */ +void CreateGeometry( Geometry& geometry ) +{ + struct QuadVertex { Vector2 position; }; + + QuadVertex quadVertexData[4] = + { + { Vector2( 0.0f, 0.0f) }, + { Vector2( 1.0f, 0.0f) }, + { Vector2( 0.0f, 1.0f) }, + { Vector2( 1.0f, 1.0f) }, + }; + + const unsigned short indices[6] = + { + 3,1,0,0,2,3 + }; + + Property::Map quadVertexFormat; + quadVertexFormat["aPosition"] = Property::VECTOR2; + PropertyBuffer quadVertices = PropertyBuffer::New( quadVertexFormat ); + quadVertices.SetData(quadVertexData, 4 ); + + geometry = Geometry::New(); + geometry.AddVertexBuffer( quadVertices ); + geometry.SetIndexBuffer( indices, sizeof(indices)/sizeof(indices[0]) ); +} + + +/** + * @brief Create a renderer + * + * @param[in] frameBufferImage texture to be used + * @param[out] renderer mesh renderer using the supplied texture + */ +void CreateRenderer( FrameBufferImage frameBufferImage, Dali::Renderer& renderer ) +{ + Shader shader = Shader::New( VERTEX_SHADER_SCROLL , FRAGMENT_SHADER, Shader::Hint::NONE ); + + Sampler sampler = Sampler::New(); + sampler.SetFilterMode(FilterMode::LINEAR, FilterMode::LINEAR ); + + TextureSet textureSet = TextureSet::New(); + TextureSetImage( textureSet, 0u, frameBufferImage ); + textureSet.SetSampler( 0u, sampler ); + + Geometry meshGeometry; + CreateGeometry( meshGeometry ); + + renderer = Renderer::New( meshGeometry, shader ); + renderer.SetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, true ); + renderer.SetTextures( textureSet ); +} } // namespace @@ -215,6 +311,7 @@ void TextScroller::StopScrolling() case DevelTextLabel::AutoScrollStopMode::IMMEDIATE: { mScrollAnimation.Stop(); + CleanUp(); mScrollerInterface.ScrollingFinished(); break; } @@ -236,28 +333,38 @@ DevelTextLabel::AutoScrollStopMode::Type TextScroller::GetStopMode() const return mStopMode; } -TextScroller::TextScroller( ScrollerInterface& scrollerInterface ) -: mScrollerInterface( scrollerInterface ), - mScrollDeltaIndex( Property::INVALID_INDEX ), - mScrollSpeed( MINIMUM_SCROLL_SPEED ), - mLoopCount( 1 ), - mLoopDelay( 0.0f ), - mWrapGap( 0.0f ), - mStopMode( DevelTextLabel::AutoScrollStopMode::FINISH_LOOP ) +Actor TextScroller::GetSourceCamera() const +{ + return mOffscreenCameraActor; +} + +Actor TextScroller::GetScrollingText() const +{ + return mScrollingTextActor; +} + +TextScroller::TextScroller( ScrollerInterface& scrollerInterface ) : mScrollerInterface( scrollerInterface ), + mScrollDeltaIndex( Property::INVALID_INDEX ), + mScrollSpeed( MINIMUM_SCROLL_SPEED ), + mLoopCount( 1 ), + mLoopDelay( 0.0f ), + mWrapGap( 0.0f ), + mStopMode( DevelTextLabel::AutoScrollStopMode::FINISH_LOOP ) { DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller Default Constructor\n" ); } TextScroller::~TextScroller() { + CleanUp(); } -void TextScroller::SetParameters( Actor scrollingTextActor, Renderer renderer, TextureSet textureSet, const Size& controlSize, const Size& textNaturalSize, CharacterDirection direction, Layout::HorizontalAlignment horizontalAlignment, Layout::VerticalAlignment verticalAlignment ) +void TextScroller::SetParameters( Actor sourceActor, const Size& controlSize, const Size& offScreenSize, CharacterDirection direction, float alignmentOffset, Layout::HorizontalAlignment horizontalAlignment ) { - DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetParameters controlSize[%f,%f] offscreenSize[%f,%f] direction[%d]\n", - controlSize.x, controlSize.y, textNaturalSize.x, textNaturalSize.y, direction ); + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetParameters controlSize[%f,%f] offscreenSize[%f,%f] direction[%d] alignmentOffset[%f]\n", + controlSize.x, controlSize.y, offScreenSize.x, offScreenSize.y, direction, alignmentOffset ); - mRenderer = renderer; + CleanUp(); // If already scrolling then restart with new parameters float animationProgress = 0.0f; int remainedLoop = mLoopCount; @@ -274,69 +381,114 @@ void TextScroller::SetParameters( Actor scrollingTextActor, Renderer renderer, T } } mScrollAnimation.Clear(); + } + + FrameBufferImage offscreenRenderTargetForText = FrameBufferImage::New( offScreenSize.width, offScreenSize.height, Pixel::RGBA8888 ); + Renderer renderer; - // Reset to the original shader and texture before scrolling - mRenderer.SetShader(mShader); - mRenderer.SetTextures( mTextureSet ); + CreateCameraActor( offScreenSize, mOffscreenCameraActor ); + CreateRenderer( offscreenRenderTargetForText, renderer ); + CreateRenderTask( sourceActor, mOffscreenCameraActor, offscreenRenderTargetForText, mRenderTask ); + + float xPosition = 0.0f; + switch( horizontalAlignment ) + { + case Layout::HORIZONTAL_ALIGN_BEGIN: + { + // Reposition camera to match alignment of target, RTL text has direction=true + if ( direction ) + { + xPosition = alignmentOffset + offScreenSize.width * 0.5f; + } + else + { + xPosition = offScreenSize.width * 0.5f; + } + break; + } + + case Layout::HORIZONTAL_ALIGN_CENTER: + { + xPosition = controlSize.width * 0.5f; + break; + } + + case Layout::HORIZONTAL_ALIGN_END: + { + // Reposition camera to match alignment of target, RTL text has direction=true + if ( direction ) + { + xPosition = offScreenSize.width * 0.5f; + } + else + { + xPosition = alignmentOffset + offScreenSize.width * 0.5f; + } + break; + } } - mShader = mRenderer.GetShader(); - mTextureSet = mRenderer.GetTextures(); + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetParameters xPosition[%f]\n", xPosition ); - // Set the shader and texture for scrolling - Shader shader = Shader::New( VERTEX_SHADER_SCROLL, FRAGMENT_SHADER, Shader::Hint::NONE ); - mRenderer.SetShader( shader ); - mRenderer.SetTextures( textureSet ); + mOffscreenCameraActor.SetX( xPosition ); + mOffscreenCameraActor.SetY( offScreenSize.height * 0.5f ); DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetParameters mWrapGap[%f]\n", mWrapGap ); - const float horizontalAlign = HORIZONTAL_ALIGNMENT_TABLE[ horizontalAlignment ][ direction ]; - const float verticalAlign = VERTICAL_ALIGNMENT_TABLE[ verticalAlignment ]; - DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetParameters horizontalAlign[%f], verticalAlign[%f]\n", horizontalAlign, verticalAlign ); + const float align = ALIGNMENT_TABLE[ horizontalAlignment ][ direction ][ offScreenSize.width > controlSize.width ]; + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetParameters align[%f]\n", align ); - scrollingTextActor.RegisterProperty( "uTextureSize", textNaturalSize ); - scrollingTextActor.RegisterProperty( "uHorizontalAlign", horizontalAlign ); - scrollingTextActor.RegisterProperty( "uVerticalAlign", verticalAlign ); - scrollingTextActor.RegisterProperty( "uGap", mWrapGap ); - mScrollDeltaIndex = scrollingTextActor.RegisterProperty( "uDelta", 0.0f ); + mScrollingTextActor = Actor::New(); + mScrollingTextActor.AddRenderer( renderer ); + mScrollingTextActor.RegisterProperty( "uTextureSize", offScreenSize ); + mScrollingTextActor.RegisterProperty( "uAlign", align ); + mScrollingTextActor.RegisterProperty( "uGap", mWrapGap ); + mScrollingTextActor.SetSize( controlSize.width, std::min( offScreenSize.height, controlSize.height ) ); + mScrollDeltaIndex = mScrollingTextActor.RegisterProperty( "uDelta", 0.0f ); - float scrollAmount = std::max( textNaturalSize.width + mWrapGap, controlSize.width ); + float scrollAmount = std::max( offScreenSize.width + mWrapGap, controlSize.width ); float scrollDuration = scrollAmount / mScrollSpeed; if ( direction ) { - scrollAmount = -scrollAmount; // reverse direction of scrolling + scrollAmount = -scrollAmount; // reverse direction of scrollung } - StartScrolling( scrollingTextActor, scrollAmount, scrollDuration, remainedLoop ); + StartScrolling( scrollAmount, scrollDuration, remainedLoop ); mScrollAnimation.SetCurrentProgress(animationProgress); } void TextScroller::AutoScrollAnimationFinished( Dali::Animation& animation ) { DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::AutoScrollAnimationFinished\n" ); + CleanUp(); mScrollerInterface.ScrollingFinished(); - - // Revert to the original shader and texture after scrolling - mRenderer.SetShader(mShader); - if ( mTextureSet ) - { - mRenderer.SetTextures( mTextureSet ); - } } -void TextScroller::StartScrolling( Actor scrollingTextActor, float scrollAmount, float scrollDuration, int loopCount ) +void TextScroller::StartScrolling( float scrollAmount, float scrollDuration, int loopCount ) { DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::StartScrolling scrollAmount[%f] scrollDuration[%f], loop[%d] speed[%d]\n", scrollAmount, scrollDuration, loopCount, mScrollSpeed ); mScrollAnimation = Animation::New( scrollDuration ); - mScrollAnimation.AnimateTo( Property( scrollingTextActor, mScrollDeltaIndex ), scrollAmount, TimePeriod( mLoopDelay, scrollDuration ) ); + mScrollAnimation.AnimateTo( Property( mScrollingTextActor, mScrollDeltaIndex ), scrollAmount, TimePeriod( mLoopDelay, scrollDuration ) ); mScrollAnimation.SetEndAction( Animation::Discard ); mScrollAnimation.SetLoopCount( loopCount ); mScrollAnimation.FinishedSignal().Connect( this, &TextScroller::AutoScrollAnimationFinished ); mScrollAnimation.Play(); } +void TextScroller::CleanUp() +{ + if ( Stage::IsInstalled() ) + { + Stage stage = Stage::GetCurrent(); + RenderTaskList taskList = stage.GetRenderTaskList(); + UnparentAndReset( mScrollingTextActor ); + UnparentAndReset( mOffscreenCameraActor ); + taskList.RemoveTask( mRenderTask ); + } +} + } // namespace Text } // namespace Toolkit diff --git a/dali-toolkit/internal/text/text-scroller.h b/dali-toolkit/internal/text/text-scroller.h index b8dc10f..2d611bb 100644 --- a/dali-toolkit/internal/text/text-scroller.h +++ b/dali-toolkit/internal/text/text-scroller.h @@ -22,7 +22,6 @@ #include #include #include -#include // INTERNAL INCLUDES #include @@ -61,16 +60,14 @@ public: /** * @brief Set parameters relating to source required for scrolling * - * @param[in] scrollingTextActor actor containing the text to be scrolled - * @param[in] renderer renderer to render the text - * @param[in] textureSet texture of the text to be scrolled + * @param[in] sourceActor source actor to be scrolled * @param[in] controlSize size of the control to scroll within - * @param[in] textNaturalSize natural size of the text + * @param[in] offScreenSize size of the sourceActor * @param[in] direction text direction true for right to left text - * @param[in] horizontalAlignment horizontal alignment of the text - * @param[in] verticalAlignment vertical alignment of the text + * @param[in] alignmentOffset alignment of source text + * */ - void SetParameters( Actor scrollingTextActor, Dali::Renderer renderer, TextureSet textureSet, const Size& controlSize, const Size& offScreenSize, CharacterDirection direction, Layout::HorizontalAlignment horizontalAlignment, Layout::VerticalAlignment verticalAlignment ); + void SetParameters( Actor sourceActor, const Size& controlSize, const Size& offScreenSize, CharacterDirection direction, float alignmentOffset, Layout::HorizontalAlignment horizontalAlignment ); /** * @brief Set the gap distance to elapse before the text wraps around @@ -137,6 +134,18 @@ public: */ DevelTextLabel::AutoScrollStopMode::Type GetStopMode() const; + /** + * @brief Get the camera used to look at source, should be added to the parent of target actor. + * @return camera Actor + */ + Actor GetSourceCamera() const; + + /** + * @brief Get the resulting scrolling text actor, add to target actor which will show scrolling text + * @return mesh Actor + */ + Actor GetScrollingText() const; + private: // Implementation /** @@ -163,21 +172,25 @@ private: // Implementation /** * @brief variables required to set up scrolling animation - * @param[in] scrollingTextActor actor that shows scrolling text * @param[in] scrollAmount distance to animate text for the given duration * @param[in] scrollDuration duration of aninmation * @param[in] loopCount number of times to loop the scrolling text */ - void StartScrolling( Actor scrollingTextActor, float scrollAmount, float scrollDuration, int loopCount ); + void StartScrolling( float scrollAmount, float scrollDuration, int loopCount ); + + /** + * @brief When scrolling ended, the actors are cleaned up so no longer staged. + */ + void CleanUp(); private: + RenderTask mRenderTask; // Renders full text to a FrameBuffer which is then scrolled. + CameraActor mOffscreenCameraActor; // Camera used by render task + Actor mScrollingTextActor; // Actor used to show scrolling text ScrollerInterface& mScrollerInterface; // Interface implemented by control that requires scrolling Property::Index mScrollDeltaIndex; // Property used by shader to represent distance to scroll Animation mScrollAnimation; // Animation used to update the mScrollDeltaIndex - Dali::Renderer mRenderer; // Renderer used to render the text - Shader mShader; // Shader originally used by the renderer while not scrolling - TextureSet mTextureSet; // Texture originally used by the renderer while not scrolling int mScrollSpeed; ///< Speed which text should automatically scroll at int mLoopCount; ///< Number of time the text should scroll diff --git a/dali-toolkit/internal/text/text-view.cpp b/dali-toolkit/internal/text/text-view.cpp index 9e8d0be..754b06d 100644 --- a/dali-toolkit/internal/text/text-view.cpp +++ b/dali-toolkit/internal/text/text-view.cpp @@ -384,7 +384,7 @@ Length View::GetNumberOfUnderlineRuns() const { if( mImpl->mVisualModel ) { - return mImpl->mVisualModel->GetNumberOfUnderlineRuns(); + return mImpl->mVisualModel->mUnderlineRuns.Count(); } return 0u; diff --git a/dali-toolkit/internal/text/visual-model-impl.cpp b/dali-toolkit/internal/text/visual-model-impl.cpp index 1b114c4..2ee0bab 100644 --- a/dali-toolkit/internal/text/visual-model-impl.cpp +++ b/dali-toolkit/internal/text/visual-model-impl.cpp @@ -390,11 +390,6 @@ float VisualModel::GetUnderlineHeight() const return mUnderlineHeight; } -Length VisualModel::GetNumberOfUnderlineRuns() const -{ - return mUnderlineRuns.Count(); -} - void VisualModel::ClearCaches() { mCachedLineIndex = 0u; diff --git a/dali-toolkit/internal/text/visual-model-impl.h b/dali-toolkit/internal/text/visual-model-impl.h index 6356f32..0874c05 100644 --- a/dali-toolkit/internal/text/visual-model-impl.h +++ b/dali-toolkit/internal/text/visual-model-impl.h @@ -280,13 +280,6 @@ public: */ float GetUnderlineHeight() const; - /** - * @brief Retrieves the number of underline runs. - * - * @return The number of underline runs. - */ - Length GetNumberOfUnderlineRuns() const; - protected: /** diff --git a/dali-toolkit/internal/visuals/text/text-visual.cpp b/dali-toolkit/internal/visuals/text/text-visual.cpp index 46cb2a1..7ce455e 100644 --- a/dali-toolkit/internal/visuals/text/text-visual.cpp +++ b/dali-toolkit/internal/visuals/text/text-visual.cpp @@ -18,9 +18,6 @@ // CLASS HEADER #include -// EXTERNAL INCLUDES -#include - // INTERNAL HEADER #include #include @@ -30,7 +27,6 @@ #include #include #include -#include namespace Dali { @@ -53,8 +49,6 @@ const char * const HORIZONTAL_ALIGNMENT_PROPERTY( "horizontalAlignment" ); const char * const VERTICAL_ALIGNMENT_PROPERTY( "verticalAlignment" ); const char * const TEXT_COLOR_PROPERTY( "textColor" ); const char * const ENABLE_MARKUP_PROPERTY( "enableMarkup" ); -const char * const SHADOW_PROPERTY( "shadow" ); -const char * const UNDERLINE_PROPERTY( "underline" ); const Scripting::StringEnum HORIZONTAL_ALIGNMENT_STRING_TABLE[] = { @@ -96,14 +90,14 @@ const char* VERTEX_SHADER = DALI_COMPOSE_SHADER( attribute mediump vec2 aPosition;\n uniform mediump mat4 uMvpMatrix;\n uniform mediump vec3 uSize;\n - uniform mediump vec4 pixelArea;\n + uniform mediump vec4 pixelArea; uniform mediump mat4 uModelMatrix;\n uniform mediump mat4 uViewMatrix;\n uniform mediump mat4 uProjection;\n varying mediump vec2 vTexCoord;\n - + \n //Visual size and offset uniform mediump vec2 offset;\n uniform mediump vec2 size;\n @@ -130,34 +124,18 @@ const char* VERTEX_SHADER = DALI_COMPOSE_SHADER( ); const char* FRAGMENT_SHADER_ATLAS_CLAMP = DALI_COMPOSE_SHADER( - varying mediump vec2 vTexCoord;\n - uniform sampler2D sTexture;\n - uniform sampler2D sStyle;\n - uniform sampler2D sMask;\n - uniform lowp float uHasMultipleTextColors;\n - uniform lowp vec4 uTextColorAnimatable;\n - uniform mediump vec4 uAtlasRect;\n - uniform lowp vec4 uColor;\n - uniform lowp vec3 mixColor;\n - uniform lowp float opacity;\n - \n - void main()\n - {\n - mediump vec2 texCoord = clamp( mix( uAtlasRect.xy, uAtlasRect.zw, vTexCoord ), uAtlasRect.xy, uAtlasRect.zw );\n - mediump vec4 textTexture = texture2D( sTexture, texCoord );\n - mediump vec4 styleTexture = texture2D( sStyle, texCoord );\n - mediump vec4 maskTexture = texture2D( sMask, texCoord );\n - - // Set the color of non-transparent pixel in text to what it is animated to. - // Markup text with multiple text colors are not animated (but can be supported later on if required). - // Emoji color are not animated. - mediump vec4 textColor = textTexture * textTexture.a;\n - mediump float vstep = step( 0.0001, textColor.a );\n - textColor.rgb = mix( textColor.rgb, uTextColorAnimatable.rgb, vstep * maskTexture.a * ( 1.0 - uHasMultipleTextColors ) );\n - - // Draw the text as overlay above the style - gl_FragColor = ( textColor + styleTexture * ( 1.0 - textTexture.a ) ) * uColor * vec4( mixColor, opacity );\n - }\n + varying mediump vec2 vTexCoord;\n + uniform sampler2D sTexture;\n + uniform mediump vec4 uAtlasRect;\n + uniform lowp vec4 uColor;\n + uniform lowp vec3 mixColor;\n + uniform lowp float opacity;\n + \n + void main()\n + {\n + mediump vec2 texCoord = clamp( mix( uAtlasRect.xy, uAtlasRect.zw, vTexCoord ), uAtlasRect.xy, uAtlasRect.zw );\n + gl_FragColor = texture2D( sTexture, texCoord ) * uColor * vec4( mixColor, opacity );\n + }\n ); /** @@ -210,14 +188,6 @@ Dali::Property::Index StringKeyToIndexKey( const std::string& stringKey ) { result = Toolkit::TextVisual::Property::ENABLE_MARKUP; } - else if( stringKey == SHADOW_PROPERTY ) - { - result = Toolkit::TextVisual::Property::SHADOW; - } - else if( stringKey == UNDERLINE_PROPERTY ) - { - result = Toolkit::TextVisual::Property::UNDERLINE; - } return result; } @@ -289,12 +259,6 @@ void TextVisual::DoCreatePropertyMap( Property::Map& map ) const map.Insert( Toolkit::TextVisual::Property::TEXT_COLOR, mController->GetDefaultColor() ); map.Insert( Toolkit::TextVisual::Property::ENABLE_MARKUP, mController->IsMarkupProcessorEnabled() ); - - GetShadowProperties( mController, value, Text::EffectStyle::DEFAULT ); - map.Insert( Toolkit::TextVisual::Property::SHADOW, value ); - - GetUnderlineProperties( mController, value, Text::EffectStyle::DEFAULT ); - map.Insert( Toolkit::TextVisual::Property::UNDERLINE, value ); } void TextVisual::DoCreateInstancePropertyMap( Property::Map& map ) const @@ -310,9 +274,7 @@ void TextVisual::DoCreateInstancePropertyMap( Property::Map& map ) const TextVisual::TextVisual( VisualFactoryCache& factoryCache ) : Visual::Base( factoryCache ), mController( Text::Controller::New() ), - mTypesetter( Text::Typesetter::New( mController->GetTextModel() ) ), - mAnimatableTextColorPropertyIndex( Property::INVALID_INDEX ), - mRendererUpdateNeeded( false ) + mTypesetter( Text::Typesetter::New( mController->GetTextModel() ) ) { } @@ -364,24 +326,7 @@ void TextVisual::DoSetOnStage( Actor& actor ) mImpl->mRenderer = Renderer::New( geometry, shader ); mImpl->mRenderer.SetProperty( Dali::Renderer::Property::DEPTH_INDEX, Toolkit::DepthIndex::CONTENT ); - const Vector4& defaultColor = mController->GetTextModel()->GetDefaultColor(); - Dali::Property::Index shaderTextColorIndex = mImpl->mRenderer.RegisterProperty( "uTextColorAnimatable", defaultColor ); - - if ( mAnimatableTextColorPropertyIndex != Property::INVALID_INDEX ) - { - // Create constraint for the animatable text's color Property with uTextColorAnimatable in the renderer. - if( shaderTextColorIndex != Property::INVALID_INDEX ) - { - Constraint constraint = Constraint::New( mImpl->mRenderer, shaderTextColorIndex, EqualToConstraint() ); - constraint.AddSource( Source( actor, mAnimatableTextColorPropertyIndex ) ); - constraint.Apply(); - } - } - - // Renderer needs textures and to be added to control - mRendererUpdateNeeded = true; - - UpdateRenderer(); + UpdateRenderer( true ); // Renderer needs textures and to be added to control } void TextVisual::DoSetOffStage( Actor& actor ) @@ -403,7 +348,7 @@ void TextVisual::DoSetOffStage( Actor& actor ) void TextVisual::OnSetTransform() { - UpdateRenderer(); + UpdateRenderer( false ); } void TextVisual::DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue ) @@ -478,20 +423,10 @@ void TextVisual::DoSetProperty( Dali::Property::Index index, const Dali::Propert } break; } - case Toolkit::TextVisual::Property::SHADOW: - { - SetShadowProperties( mController, propertyValue, Text::EffectStyle::DEFAULT ); - break; - } - case Toolkit::TextVisual::Property::UNDERLINE: - { - SetUnderlineProperties( mController, propertyValue, Text::EffectStyle::DEFAULT ); - break; - } } } -void TextVisual::UpdateRenderer() +void TextVisual::UpdateRenderer( bool initializeRendererAndTexture ) { Actor control = mControl.GetHandle(); if( !control ) @@ -528,11 +463,8 @@ void TextVisual::UpdateRenderer() const Text::Controller::UpdateTextType updateTextType = mController->Relayout( relayoutSize ); - if( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType ) - || mRendererUpdateNeeded ) + if( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType ) || initializeRendererAndTexture ) { - mRendererUpdateNeeded = false; - // Removes the texture set. RemoveTextureSet(); @@ -545,10 +477,11 @@ void TextVisual::UpdateRenderer() if( ( relayoutSize.width > Math::MACHINE_EPSILON_1000 ) && ( relayoutSize.height > Math::MACHINE_EPSILON_1000 ) ) { + PixelData data = mTypesetter->Render( relayoutSize ); + Vector4 atlasRect = FULL_TEXTURE_RECT; - // Create a texture for the text without any styles - PixelData data = mTypesetter->Render( relayoutSize, Text::Typesetter::RENDER_NO_STYLES ); + // Texture set not retrieved from Atlas Manager whilst pixel offset visible. // It may happen the image atlas can't handle a pixel data it exceeds the maximum size. // In that case, create a texture. TODO: should tile the text. @@ -563,51 +496,20 @@ void TextVisual::UpdateRenderer() TextureSet textureSet = TextureSet::New(); textureSet.SetTexture( 0u, texture ); - // Create a texture for all the text styles (without the text itself) - PixelData styleData = mTypesetter->Render( relayoutSize, Text::Typesetter::RENDER_NO_TEXT ); - - Texture styleTexture = Texture::New( Dali::TextureType::TEXTURE_2D, - styleData.GetPixelFormat(), - styleData.GetWidth(), - styleData.GetHeight() ); - - styleTexture.Upload( styleData ); - - textureSet.SetTexture( 1u, styleTexture ); - - // Create a texture as a mask to avoid color glyphs (e.g. emojis) to be affected by text color animation - PixelData maskData = mTypesetter->Render( relayoutSize, Text::Typesetter::RENDER_MASK ); - - Texture maskTexture = Texture::New( Dali::TextureType::TEXTURE_2D, - styleData.GetPixelFormat(), - styleData.GetWidth(), - styleData.GetHeight() ); + mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED; - maskTexture.Upload( maskData ); + mImpl->mRenderer.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, atlasRect ); - textureSet.SetTexture( 2u, maskTexture ); + //Register transform properties + mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT ); - // Filter mode needs to be set to linear to produce better quality while scaling. + // Filter mode needs to be set to nearest to avoid blurry text. Sampler sampler = Sampler::New(); - sampler.SetFilterMode( FilterMode::LINEAR, FilterMode::LINEAR ); + sampler.SetFilterMode( FilterMode::NEAREST, FilterMode::NEAREST ); textureSet.SetSampler( 0u, sampler ); - textureSet.SetSampler( 1u, sampler ); - textureSet.SetSampler( 2u, sampler ); mImpl->mRenderer.SetTextures( textureSet ); - mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED; - - mImpl->mRenderer.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, atlasRect ); - - // Check whether it is a markup text with multiple text colors - const Vector4* const colorsBuffer = mController->GetTextModel()->GetColors(); - bool hasMultipleTextColors = ( NULL != colorsBuffer ); - mImpl->mRenderer.RegisterProperty( "uHasMultipleTextColors", static_cast( hasMultipleTextColors ) ); - - //Register transform properties - mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT ); - control.AddRenderer( mImpl->mRenderer ); // Text rendered and ready to display diff --git a/dali-toolkit/internal/visuals/text/text-visual.h b/dali-toolkit/internal/visuals/text/text-visual.h index 2ed7bee..8222276 100644 --- a/dali-toolkit/internal/visuals/text/text-visual.h +++ b/dali-toolkit/internal/visuals/text/text-visual.h @@ -18,9 +18,6 @@ * */ -// EXTERNAL INCLUDES -#include - // INTERNAL INCLUDES #include #include @@ -84,35 +81,6 @@ public: */ static void ConvertStringKeysToIndexKeys( Property::Map& propertyMap ); - /** - * @brief Retrieve the text's controller. - * @param[in] visual The text visual. - * @return The text controller - */ - static Text::ControllerPtr GetController( Toolkit::Visual::Base visual ) - { - return GetVisualObject( visual ).mController; - }; - - /** - * @brief Set the index of the animatable text color property. - * @param[in] visual The text visual. - * @param[in] animatablePropertyIndex The index of the animatable property - */ - static void SetAnimatableTextColorProperty( Toolkit::Visual::Base visual, Property::Index animatablePropertyIndex ) - { - GetVisualObject( visual ).mAnimatableTextColorPropertyIndex = animatablePropertyIndex; - }; - - /** - * @brief Set the flag to trigger the textures to be initialized and renderer to be added to the control. - * @param[in] visual The text visual. - */ - static void EnableRendererUpdate( Toolkit::Visual::Base visual ) - { - GetVisualObject( visual ).mRendererUpdateNeeded = true; - }; - public: // from Visual::Base /** @@ -183,30 +151,19 @@ private: /** * @brief Updates the text's renderer. + * @param[in] initializeRendererAndTexture Set flag to true to initialize textures and add renderer to control. */ - void UpdateRenderer(); + void UpdateRenderer( bool initializeRendererAndTexture ); /** * @brief Removes the texture set from the renderer. */ void RemoveTextureSet(); - /** - * @brief Retrieve the text's controller. - * @param[in] visual The text visual. - * @return The text controller - */ - static TextVisual& GetVisualObject( Toolkit::Visual::Base visual ) - { - return static_cast( visual.GetBaseObject() ); - }; - private: - Text::ControllerPtr mController; ///< The text's controller. - Text::TypesetterPtr mTypesetter; ///< The text's typesetter. - WeakHandle mControl; ///< The control where the renderer is added. - Property::Index mAnimatableTextColorPropertyIndex; ///< The index of animatable text color property registered by the control. - bool mRendererUpdateNeeded:1; ///< The flag to indicate whether the renderer needs to be updated. + Text::ControllerPtr mController; ///< The text's controller. + Text::TypesetterPtr mTypesetter; ///< The text's typesetter. + WeakHandle mControl; ///< The control where the renderer is added. }; } // namespace Internal diff --git a/dali-toolkit/public-api/controls/text-controls/text-label.h b/dali-toolkit/public-api/controls/text-controls/text-label.h index df0abce..5674716 100644 --- a/dali-toolkit/public-api/controls/text-controls/text-label.h +++ b/dali-toolkit/public-api/controls/text-controls/text-label.h @@ -90,7 +90,6 @@ public: enum { /** - * DEPRECATED_1_2.53 No longer be supported and will be ignored. * @brief The type of rendering e.g. bitmap-based. * @details name "renderingBackend", type INT, default RENDERING_SHARED_ATLAS. * @SINCE_1_0.0 diff --git a/dali-toolkit/public-api/dali-toolkit-version.cpp b/dali-toolkit/public-api/dali-toolkit-version.cpp index 07f851c..8417ead 100644 --- a/dali-toolkit/public-api/dali-toolkit-version.cpp +++ b/dali-toolkit/public-api/dali-toolkit-version.cpp @@ -31,7 +31,7 @@ namespace Toolkit const unsigned int TOOLKIT_MAJOR_VERSION = 1; const unsigned int TOOLKIT_MINOR_VERSION = 2; -const unsigned int TOOLKIT_MICRO_VERSION = 55; +const unsigned int TOOLKIT_MICRO_VERSION = 56; const char * const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__; #ifdef DEBUG_ENABLED diff --git a/dali-toolkit/public-api/visuals/image-visual-properties.h b/dali-toolkit/public-api/visuals/image-visual-properties.h index 44d5692..8eff9fa 100644 --- a/dali-toolkit/public-api/visuals/image-visual-properties.h +++ b/dali-toolkit/public-api/visuals/image-visual-properties.h @@ -56,6 +56,9 @@ enum * @brief The URL of the image. * @details Name "url", type Property::STRING or Property::ARRAY of Property::STRING * @note The array form is used for generating animated image visuals. + * @note The number of threads used for local and remote image loading can be controlled by the + * environment variables DALI_TEXTURE_LOCAL_THREADS and DALI_TEXTURE_REMOTE_THREADS respectively. + * The default values are 4 threads for local image loading and 8 threads for remote image loading. * @SINCE_1_1.45 * @note Mandatory. */ diff --git a/packaging/dali-toolkit.spec b/packaging/dali-toolkit.spec index 0414a58..fc6b10e 100644 --- a/packaging/dali-toolkit.spec +++ b/packaging/dali-toolkit.spec @@ -1,6 +1,6 @@ Name: dali-toolkit Summary: Dali 3D engine Toolkit -Version: 1.2.55 +Version: 1.2.56 Release: 1 Group: System/Libraries License: Apache-2.0 and BSD-3-Clause and MIT