From 583538010c34b92f80989021201484fdf9e590a9 Mon Sep 17 00:00:00 2001 From: Adeel Kazmi Date: Fri, 16 Oct 2020 12:06:40 +0100 Subject: [PATCH 1/1] Reduce Cyclomatic Complexity of some methods in text-typesetter, transtion-data & text-label Change-Id: I7c9a5b8c2ffc59837b0e8bcf85f78fe96df1bf9c --- .../controls/text-controls/text-label-impl.cpp | 256 +++++++++------------ .../controls/text-controls/text-label-impl.h | 15 +- .../internal/text/rendering/text-typesetter.cpp | 253 +++++++++++--------- .../internal/visuals/transition-data-impl.cpp | 209 +++++++++-------- 4 files changed, 376 insertions(+), 357 deletions(-) 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 1cdb0f8..d1c1b1a 100755 --- a/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp @@ -62,33 +62,29 @@ namespace Internal namespace { - const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::DevelText::DEFAULT_RENDERING_BACKEND; - - /** - * @brief How the text visual should be aligned vertically inside the control. - * - * 0.0f aligns the text to the top, 0.5f aligns the text to the center, 1.0f aligns the text to the bottom. - * The alignment depends on the alignment value of the text label (Use Text::VerticalAlignment enumerations). - */ - const float VERTICAL_ALIGNMENT_TABLE[ Text::VerticalAlignment::BOTTOM + 1 ] = - { - 0.0f, // VerticalAlignment::TOP - 0.5f, // VerticalAlignment::CENTER - 1.0f // VerticalAlignment::BOTTOM - }; - - const std::string TEXT_FIT_ENABLE_KEY( "enable" ); - const std::string TEXT_FIT_MIN_SIZE_KEY( "minSize" ); - const std::string TEXT_FIT_MAX_SIZE_KEY( "maxSize" ); - const std::string TEXT_FIT_STEP_SIZE_KEY( "stepSize" ); - const std::string TEXT_FIT_FONT_SIZE_TYPE_KEY( "fontSizeType" ); -} +const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::DevelText::DEFAULT_RENDERING_BACKEND; -namespace +/** + * @brief How the text visual should be aligned vertically inside the control. + * + * 0.0f aligns the text to the top, 0.5f aligns the text to the center, 1.0f aligns the text to the bottom. + * The alignment depends on the alignment value of the text label (Use Text::VerticalAlignment enumerations). + */ +const float VERTICAL_ALIGNMENT_TABLE[ Text::VerticalAlignment::BOTTOM + 1 ] = { + 0.0f, // VerticalAlignment::TOP + 0.5f, // VerticalAlignment::CENTER + 1.0f // VerticalAlignment::BOTTOM +}; + +const std::string TEXT_FIT_ENABLE_KEY( "enable" ); +const std::string TEXT_FIT_MIN_SIZE_KEY( "minSize" ); +const std::string TEXT_FIT_MAX_SIZE_KEY( "maxSize" ); +const std::string TEXT_FIT_STEP_SIZE_KEY( "stepSize" ); +const std::string TEXT_FIT_FONT_SIZE_TYPE_KEY( "fontSizeType" ); #if defined ( DEBUG_ENABLED ) - Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_CONTROLS"); +Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_CONTROLS"); #endif const Scripting::StringEnum AUTO_SCROLL_STOP_MODE_TABLE[] = @@ -145,6 +141,73 @@ DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit, TextLabel, "textCol DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit, TextLabel, "textColorAlpha", TEXT_COLOR_ALPHA, TEXT_COLOR, 3 ) DALI_TYPE_REGISTRATION_END() +/// Parses the property map for the TEXT_FIT property +void ParseTextFitProperty(Text::ControllerPtr& controller, const Property::Map* propertiesMap) +{ + if ( propertiesMap && !propertiesMap->Empty() ) + { + bool enabled = false; + float minSize = 0.f; + float maxSize = 0.f; + float stepSize = 0.f; + bool isMinSizeSet = false, isMaxSizeSet = false, isStepSizeSet = false; + Controller::FontSizeType type = Controller::FontSizeType::POINT_SIZE; + + const unsigned int numberOfItems = propertiesMap->Count(); + + // Parses and applies + for( unsigned int index = 0u; index < numberOfItems; ++index ) + { + const KeyValuePair& valueGet = propertiesMap->GetKeyValue( index ); + + if( ( Controller::TextFitInfo::Property::TEXT_FIT_ENABLE == valueGet.first.indexKey ) || ( TEXT_FIT_ENABLE_KEY == valueGet.first.stringKey ) ) + { + /// Enable key. + enabled = valueGet.second.Get< bool >(); + } + else if( ( Controller::TextFitInfo::Property::TEXT_FIT_MIN_SIZE == valueGet.first.indexKey ) || ( TEXT_FIT_MIN_SIZE_KEY == valueGet.first.stringKey ) ) + { + /// min size. + minSize = valueGet.second.Get< float >(); + isMinSizeSet = true; + } + else if( ( Controller::TextFitInfo::Property::TEXT_FIT_MAX_SIZE == valueGet.first.indexKey ) || ( TEXT_FIT_MAX_SIZE_KEY == valueGet.first.stringKey ) ) + { + /// max size. + maxSize = valueGet.second.Get< float >(); + isMaxSizeSet = true; + } + else if( ( Controller::TextFitInfo::Property::TEXT_FIT_STEP_SIZE == valueGet.first.indexKey ) || ( TEXT_FIT_STEP_SIZE_KEY == valueGet.first.stringKey ) ) + { + /// step size. + stepSize = valueGet.second.Get< float >(); + isStepSizeSet = true; + } + else if( ( Controller::TextFitInfo::Property::TEXT_FIT_FONT_SIZE_TYPE == valueGet.first.indexKey ) || ( TEXT_FIT_FONT_SIZE_TYPE_KEY == valueGet.first.stringKey ) ) + { + if( "pixelSize" == valueGet.second.Get< std::string >() ) + { + type = Controller::FontSizeType::PIXEL_SIZE; + } + } + } + + controller->SetTextFitEnabled( enabled ); + if( isMinSizeSet ) + { + controller->SetTextFitMinSize( minSize, type ); + } + if( isMaxSizeSet ) + { + controller->SetTextFitMaxSize( maxSize, type ); + } + if( isStepSizeSet ) + { + controller->SetTextFitStepSize( stepSize, type ); + } + } +} + } // namespace Toolkit::TextLabel TextLabel::New() @@ -275,101 +338,61 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr } case Toolkit::TextLabel::Property::AUTO_SCROLL_STOP_MODE: { - if( !impl.mTextScroller ) - { - impl.mTextScroller = Text::TextScroller::New( impl ); - } - Toolkit::TextLabel::AutoScrollStopMode::Type stopMode = impl.mTextScroller->GetStopMode(); + Text::TextScrollerPtr textScroller = impl.GetTextScroller(); + Toolkit::TextLabel::AutoScrollStopMode::Type stopMode = textScroller->GetStopMode(); if( Scripting::GetEnumerationProperty< Toolkit::TextLabel::AutoScrollStopMode::Type >( value, - AUTO_SCROLL_STOP_MODE_TABLE, - AUTO_SCROLL_STOP_MODE_TABLE_COUNT, - stopMode ) ) + AUTO_SCROLL_STOP_MODE_TABLE, + AUTO_SCROLL_STOP_MODE_TABLE_COUNT, + stopMode ) ) { - impl.mTextScroller->SetStopMode( stopMode ); + textScroller->SetStopMode( stopMode ); } break; } case Toolkit::TextLabel::Property::AUTO_SCROLL_SPEED: { - if( !impl.mTextScroller ) - { - impl.mTextScroller = Text::TextScroller::New( impl ); - } - impl.mTextScroller->SetSpeed( value.Get() ); + impl.GetTextScroller()->SetSpeed( value.Get() ); break; } case Toolkit::TextLabel::Property::AUTO_SCROLL_LOOP_COUNT: { - if( !impl.mTextScroller ) - { - impl.mTextScroller = Text::TextScroller::New( impl ); - } - impl.mTextScroller->SetLoopCount( value.Get() ); + impl.GetTextScroller()->SetLoopCount( value.Get() ); break; } case Toolkit::TextLabel::Property::AUTO_SCROLL_LOOP_DELAY: { - if( !impl.mTextScroller ) - { - impl.mTextScroller = Text::TextScroller::New( impl ); - } - impl.mTextScroller->SetLoopDelay( value.Get() ); + impl.GetTextScroller()->SetLoopDelay( value.Get() ); break; } case Toolkit::TextLabel::Property::AUTO_SCROLL_GAP: { - if( !impl.mTextScroller ) - { - impl.mTextScroller = Text::TextScroller::New( impl ); - } - impl.mTextScroller->SetGap( value.Get() ); + impl.GetTextScroller()->SetGap( value.Get() ); break; } case Toolkit::TextLabel::Property::LINE_SPACING: { const float lineSpacing = value.Get(); - - // Don't trigger anything if the line spacing didn't change - if( impl.mController->SetDefaultLineSpacing( lineSpacing ) ) - { - impl.mTextUpdateNeeded = true; - } + impl.mTextUpdateNeeded = impl.mController->SetDefaultLineSpacing( lineSpacing ) || impl.mTextUpdateNeeded; break; } case Toolkit::TextLabel::Property::UNDERLINE: { - const bool update = SetUnderlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT ); - if( update ) - { - impl.mTextUpdateNeeded = true; - } + impl.mTextUpdateNeeded = SetUnderlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT ) || impl.mTextUpdateNeeded; break; } case Toolkit::TextLabel::Property::SHADOW: { - const bool update = SetShadowProperties( impl.mController, value, Text::EffectStyle::DEFAULT ); - if( update ) - { - impl.mTextUpdateNeeded = true; - } + impl.mTextUpdateNeeded = SetShadowProperties( impl.mController, value, Text::EffectStyle::DEFAULT ) || impl.mTextUpdateNeeded; break; } case Toolkit::TextLabel::Property::EMBOSS: { - const bool update = SetEmbossProperties( impl.mController, value, Text::EffectStyle::DEFAULT ); - if( update ) - { - impl.mTextUpdateNeeded = true; - } + impl.mTextUpdateNeeded = SetEmbossProperties( impl.mController, value, Text::EffectStyle::DEFAULT ) || impl.mTextUpdateNeeded; break; } case Toolkit::TextLabel::Property::OUTLINE: { - const bool update = SetOutlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT ); - if( update ) - { - impl.mTextUpdateNeeded = true; - } + impl.mTextUpdateNeeded = SetOutlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT ) || impl.mTextUpdateNeeded; break; } case Toolkit::TextLabel::Property::PIXEL_SIZE: @@ -419,11 +442,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr } case Toolkit::DevelTextLabel::Property::BACKGROUND: { - const bool update = SetBackgroundProperties( impl.mController, value, Text::EffectStyle::DEFAULT ); - if( update ) - { - impl.mTextUpdateNeeded = true; - } + impl.mTextUpdateNeeded = SetBackgroundProperties( impl.mController, value, Text::EffectStyle::DEFAULT ) || impl.mTextUpdateNeeded; break; } case Toolkit::DevelTextLabel::Property::IGNORE_SPACES_AFTER_TEXT: @@ -438,80 +457,13 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr } case Toolkit::DevelTextLabel::Property::TEXT_FIT: { - const Property::Map& propertiesMap = value.Get(); - - bool enabled = false; - float minSize = 0.f; - float maxSize = 0.f; - float stepSize = 0.f; - bool isMinSizeSet = false, isMaxSizeSet = false, isStepSizeSet = false; - Controller::FontSizeType type = Controller::FontSizeType::POINT_SIZE; - - if ( !propertiesMap.Empty() ) - { - const unsigned int numberOfItems = propertiesMap.Count(); - - // Parses and applies - for( unsigned int index = 0u; index < numberOfItems; ++index ) - { - const KeyValuePair& valueGet = propertiesMap.GetKeyValue( index ); - - if( ( Controller::TextFitInfo::Property::TEXT_FIT_ENABLE == valueGet.first.indexKey ) || ( TEXT_FIT_ENABLE_KEY == valueGet.first.stringKey ) ) - { - /// Enable key. - enabled = valueGet.second.Get< bool >(); - } - else if( ( Controller::TextFitInfo::Property::TEXT_FIT_MIN_SIZE == valueGet.first.indexKey ) || ( TEXT_FIT_MIN_SIZE_KEY == valueGet.first.stringKey ) ) - { - /// min size. - minSize = valueGet.second.Get< float >(); - isMinSizeSet = true; - } - else if( ( Controller::TextFitInfo::Property::TEXT_FIT_MAX_SIZE == valueGet.first.indexKey ) || ( TEXT_FIT_MAX_SIZE_KEY == valueGet.first.stringKey ) ) - { - /// max size. - maxSize = valueGet.second.Get< float >(); - isMaxSizeSet = true; - } - else if( ( Controller::TextFitInfo::Property::TEXT_FIT_STEP_SIZE == valueGet.first.indexKey ) || ( TEXT_FIT_STEP_SIZE_KEY == valueGet.first.stringKey ) ) - { - /// step size. - stepSize = valueGet.second.Get< float >(); - isStepSizeSet = true; - } - else if( ( Controller::TextFitInfo::Property::TEXT_FIT_FONT_SIZE_TYPE == valueGet.first.indexKey ) || ( TEXT_FIT_FONT_SIZE_TYPE_KEY == valueGet.first.stringKey ) ) - { - if( "pixelSize" == valueGet.second.Get< std::string >() ) - { - type = Controller::FontSizeType::PIXEL_SIZE; - } - } - } - - impl.mController->SetTextFitEnabled( enabled ); - if( isMinSizeSet ) - { - impl.mController->SetTextFitMinSize( minSize, type ); - } - if( isMaxSizeSet ) - { - impl.mController->SetTextFitMaxSize( maxSize, type ); - } - if( isStepSizeSet ) - { - impl.mController->SetTextFitStepSize( stepSize, type ); - } - } + ParseTextFitProperty(impl.mController, value.GetMap()); break; } case Toolkit::DevelTextLabel::Property::MIN_LINE_SIZE: { const float lineSize = value.Get(); - - if( impl.mController->SetDefaultLineSize( lineSize ) ) - { - impl.mTextUpdateNeeded = true; - } + impl.mTextUpdateNeeded = impl.mController->SetDefaultLineSize( lineSize ) || impl.mTextUpdateNeeded; break; } } 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 bdbdbbc..a863c9c 100644 --- a/dali-toolkit/internal/controls/text-controls/text-label-impl.h +++ b/dali-toolkit/internal/controls/text-controls/text-label-impl.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_INTERNAL_TEXT_LABEL_H /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * Copyright (c) 2020 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -142,6 +142,19 @@ private: */ void SetUpAutoScrolling(); + /** + * Creates a text-scroller if one has not been created. + * @return The text scroller. + */ + Text::TextScrollerPtr GetTextScroller() + { + if( !mTextScroller ) + { + mTextScroller = Text::TextScroller::New( *this ); + } + return mTextScroller; + } + private: // Data Text::ControllerPtr mController; diff --git a/dali-toolkit/internal/text/rendering/text-typesetter.cpp b/dali-toolkit/internal/text/rendering/text-typesetter.cpp index 0256a43..05b4a67 100755 --- a/dali-toolkit/internal/text/rendering/text-typesetter.cpp +++ b/dali-toolkit/internal/text/rendering/text-typesetter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * Copyright (c) 2020 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -278,6 +278,149 @@ bool IsGlyphUnderlined( GlyphIndex index, return false; } +/// Helper method to fetch the underline metrics for the specified font glyph +void FetchFontUnderlineMetrics( + TextAbstraction::FontClient& fontClient, + const GlyphInfo* const glyphInfo, + float& currentUnderlinePosition, + const float underlineHeight, + float& currentUnderlineThickness, + float& maxUnderlineThickness, + FontId& lastUnderlinedFontId) +{ + 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; +} + +/// Draws the specified color to the pixel buffer +void WriteColorToPixelBuffer( + GlyphData& glyphData, + uint32_t* bitmapBuffer, + const Vector4& color, + const unsigned int x, + const unsigned int y) +{ + // Always RGBA image for text with styles + uint32_t pixel = *( bitmapBuffer + y * glyphData.width + x ); + uint8_t* pixelBuffer = reinterpret_cast( &pixel ); + + // Write the color to the pixel buffer + uint8_t colorAlpha = static_cast< uint8_t >( color.a * 255.f ); + *( pixelBuffer + 3u ) = colorAlpha; + *( pixelBuffer + 2u ) = static_cast< uint8_t >( color.b * colorAlpha ); + *( pixelBuffer + 1u ) = static_cast< uint8_t >( color.g * colorAlpha ); + *( pixelBuffer ) = static_cast< uint8_t >( color.r * colorAlpha ); + + *( bitmapBuffer + y * glyphData.width + x ) = pixel; +} + +/// Draws the specified underline color to the buffer +void DrawUnderline( + const Vector4& underlineColor, + const unsigned int bufferWidth, + const unsigned int bufferHeight, + GlyphData& glyphData, + const float baseline, + const float currentUnderlinePosition, + const float maxUnderlineThickness, + const float lineExtentLeft, + const float lineExtentRight) +{ + int underlineYOffset = glyphData.verticalOffset + baseline + currentUnderlinePosition; + uint32_t* bitmapBuffer = reinterpret_cast< uint32_t* >( glyphData.bitmapBuffer.GetBuffer() ); + + for( unsigned int y = underlineYOffset; y < underlineYOffset + maxUnderlineThickness; y++ ) + { + if( y > bufferHeight - 1 ) + { + // Do not write out of bounds. + break; + } + + for( unsigned int x = glyphData.horizontalOffset + lineExtentLeft; x <= glyphData.horizontalOffset + lineExtentRight; x++ ) + { + if( x > bufferWidth - 1 ) + { + // Do not write out of bounds. + break; + } + + WriteColorToPixelBuffer(glyphData, bitmapBuffer, underlineColor, x, y); + } + } +} + +/// Draws the background color to the buffer +void DrawBackgroundColor( + Vector4 backgroundColor, + const unsigned int bufferWidth, + const unsigned int bufferHeight, + GlyphData& glyphData, + const float baseline, + const LineRun& line, + const float lineExtentLeft, + const float lineExtentRight) +{ + uint32_t* bitmapBuffer = reinterpret_cast< uint32_t* >( glyphData.bitmapBuffer.GetBuffer() ); + + for( int y = glyphData.verticalOffset + baseline - line.ascender; y < glyphData.verticalOffset + baseline - line.descender; y++ ) + { + if( ( y < 0 ) || ( y > static_cast(bufferHeight - 1) ) ) + { + // Do not write out of bounds. + continue; + } + + for( int x = glyphData.horizontalOffset + lineExtentLeft; x <= glyphData.horizontalOffset + lineExtentRight; x++ ) + { + if( ( x < 0 ) || ( x > static_cast(bufferWidth - 1) ) ) + { + // Do not write out of bounds. + continue; + } + + WriteColorToPixelBuffer(glyphData, bitmapBuffer, backgroundColor, x, y); + } + } +} + } // namespace TypesetterPtr Typesetter::New( const ModelInterface* const model ) @@ -593,45 +736,7 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth 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; + FetchFontUnderlineMetrics(fontClient, glyphInfo, currentUnderlinePosition, underlineHeight, currentUnderlineThickness, maxUnderlineThickness, lastUnderlinedFontId); } // underline // Retrieves the glyph's position. @@ -728,77 +833,13 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth // 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 > bufferHeight - 1 ) - { - // Do not write out of bounds. - break; - } - - for( unsigned int x = glyphData.horizontalOffset + lineExtentLeft; x <= glyphData.horizontalOffset + lineExtentRight; x++ ) - { - if( x > bufferWidth - 1 ) - { - // Do not write out of bounds. - break; - } - - // Always RGBA image for text with styles - 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 - uint8_t colorAlpha = static_cast< uint8_t >( underlineColor.a * 255.f ); - *( underlinePixelBuffer + 3u ) = colorAlpha; - *( underlinePixelBuffer + 2u ) = static_cast< uint8_t >( underlineColor.b * colorAlpha ); - *( underlinePixelBuffer + 1u ) = static_cast< uint8_t >( underlineColor.g * colorAlpha ); - *( underlinePixelBuffer ) = static_cast< uint8_t >( underlineColor.r * colorAlpha ); - - *( bitmapBuffer + y * glyphData.width + x ) = underlinePixel; - } - } + DrawUnderline(underlineColor, bufferWidth, bufferHeight, glyphData, baseline, currentUnderlinePosition, maxUnderlineThickness, lineExtentLeft, lineExtentRight); } // Draw the background color from the leftmost glyph to the rightmost glyph if ( style == Typesetter::STYLE_BACKGROUND ) { - Vector4 backgroundColor = mModel->GetBackgroundColor(); - - for( int y = glyphData.verticalOffset + baseline - line.ascender; y < glyphData.verticalOffset + baseline - line.descender; y++ ) - { - if( ( y < 0 ) || ( y > static_cast(bufferHeight - 1) ) ) - { - // Do not write out of bounds. - continue; - } - - for( int x = glyphData.horizontalOffset + lineExtentLeft; x <= glyphData.horizontalOffset + lineExtentRight; x++ ) - { - if( ( x < 0 ) || ( x > static_cast(bufferWidth - 1) ) ) - { - // Do not write out of bounds. - continue; - } - - // Always RGBA image for text with styles - uint32_t* bitmapBuffer = reinterpret_cast< uint32_t* >( glyphData.bitmapBuffer.GetBuffer() ); - uint32_t backgroundPixel = *( bitmapBuffer + y * glyphData.width + x ); - uint8_t* backgroundPixelBuffer = reinterpret_cast( &backgroundPixel ); - - // Write the background color to the pixel buffer - uint8_t colorAlpha = static_cast< uint8_t >( backgroundColor.a * 255.f ); - *( backgroundPixelBuffer + 3u ) = colorAlpha; - *( backgroundPixelBuffer + 2u ) = static_cast< uint8_t >( backgroundColor.b * colorAlpha ); - *( backgroundPixelBuffer + 1u ) = static_cast< uint8_t >( backgroundColor.g * colorAlpha ); - *( backgroundPixelBuffer ) = static_cast< uint8_t >( backgroundColor.r * colorAlpha ); - - *( bitmapBuffer + y * glyphData.width + x ) = backgroundPixel; - } - } + DrawBackgroundColor(mModel->GetBackgroundColor(), bufferWidth, bufferHeight, glyphData, baseline, line, lineExtentLeft, lineExtentRight); } // Increases the vertical offset with the line's descender. diff --git a/dali-toolkit/internal/visuals/transition-data-impl.cpp b/dali-toolkit/internal/visuals/transition-data-impl.cpp index 78dab18..bda70a4b 100644 --- a/dali-toolkit/internal/visuals/transition-data-impl.cpp +++ b/dali-toolkit/internal/visuals/transition-data-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * Copyright (c) 2020 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -65,6 +65,114 @@ namespace Toolkit namespace Internal { +namespace +{ + +/// Parses a Property::Array and sets up the animator appropriately +void ParseArray(TransitionData::Animator* animator, const Property::Array* array) +{ + bool valid = true; + Vector4 controlPoints; + if( array && array->Count() >= 4 ) + { + for( size_t vecIdx = 0; vecIdx < 4; ++vecIdx ) + { + const Property::Value& v = array->GetElementAt(vecIdx); + if( v.GetType() == Property::FLOAT ) + { + controlPoints[vecIdx] = v.Get(); + } + else + { + valid = false; + break; + } + } + } + else + { + valid = false; + } + + if( valid ) + { + Vector2 controlPoint1( controlPoints.x, controlPoints.y ); + Vector2 controlPoint2( controlPoints.z, controlPoints.w ); + animator->alphaFunction = AlphaFunction( controlPoint1, controlPoint2 ); + } + else + { + animator->animate = false; + } +} + +/// Parses a string value and sets up the animator appropriately +void ParseString(TransitionData::Animator* animator, std::string alphaFunctionValue) +{ + if( alphaFunctionValue == "LINEAR" ) + { + animator->alphaFunction = AlphaFunction(AlphaFunction::LINEAR); + } + else if( ! alphaFunctionValue.compare(0, 5, "EASE_" ) ) + { + if( alphaFunctionValue == "EASE_IN" ) + { + animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_IN); + } + else if( alphaFunctionValue == "EASE_OUT" ) + { + animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_OUT); + } + else if( ! alphaFunctionValue.compare( 5, 3, "IN_" ) ) + { + if( ! alphaFunctionValue.compare(8, -1, "SQUARE" )) + { + animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_IN_SQUARE); + } + else if( ! alphaFunctionValue.compare(8, -1, "OUT" )) + { + animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_IN_OUT); + } + else if( ! alphaFunctionValue.compare(8, -1, "OUT_SINE" )) + { + animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_IN_OUT_SINE); + } + else if( ! alphaFunctionValue.compare(8, -1, "SINE" )) + { + animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_IN_SINE); + } + } + else if( ! alphaFunctionValue.compare( 5, 4, "OUT_" ) ) + { + if( ! alphaFunctionValue.compare(9, -1, "SQUARE" ) ) + { + animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_OUT_SQUARE); + } + else if( ! alphaFunctionValue.compare(9, -1, "SINE" ) ) + { + animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_OUT_SINE); + } + else if( ! alphaFunctionValue.compare(9, -1, "BACK" ) ) + { + animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_OUT_BACK); + } + } + } + else if( alphaFunctionValue == "REVERSE" ) + { + animator->alphaFunction = AlphaFunction(AlphaFunction::REVERSE); + } + else if( alphaFunctionValue == "BOUNCE" ) + { + animator->alphaFunction = AlphaFunction(AlphaFunction::BOUNCE); + } + else if( alphaFunctionValue == "SIN" ) + { + animator->alphaFunction = AlphaFunction(AlphaFunction::SIN); + } +} +} // unnamed namespace + TransitionData::TransitionData() { } @@ -171,40 +279,7 @@ TransitionData::Animator* TransitionData::ConvertMap( const Property::Map& map) { if( value.GetType() == Property::ARRAY ) { - bool valid = true; - Vector4 controlPoints; - const Property::Array* array = value.GetArray(); - if( array && array->Count() >= 4 ) - { - for( size_t vecIdx = 0; vecIdx < 4; ++vecIdx ) - { - const Property::Value& v = array->GetElementAt(vecIdx); - if( v.GetType() == Property::FLOAT ) - { - controlPoints[vecIdx] = v.Get(); - } - else - { - valid = false; - break; - } - } - } - else - { - valid = false; - } - - if( valid ) - { - Vector2 controlPoint1( controlPoints.x, controlPoints.y ); - Vector2 controlPoint2( controlPoints.z, controlPoints.w ); - animator->alphaFunction = AlphaFunction( controlPoint1, controlPoint2 ); - } - else - { - animator->animate = false; - } + ParseArray(animator, value.GetArray()); } else if( value.GetType() == Property::VECTOR4 ) { @@ -215,69 +290,7 @@ TransitionData::Animator* TransitionData::ConvertMap( const Property::Map& map) } else if( value.GetType() == Property::STRING ) { - std::string alphaFunctionValue = value.Get< std::string >(); - - if( alphaFunctionValue == "LINEAR" ) - { - animator->alphaFunction = AlphaFunction(AlphaFunction::LINEAR); - } - else if( ! alphaFunctionValue.compare(0, 5, "EASE_" ) ) - { - if( alphaFunctionValue == "EASE_IN" ) - { - animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_IN); - } - else if( alphaFunctionValue == "EASE_OUT" ) - { - animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_OUT); - } - else if( ! alphaFunctionValue.compare( 5, 3, "IN_" ) ) - { - if( ! alphaFunctionValue.compare(8, -1, "SQUARE" )) - { - animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_IN_SQUARE); - } - else if( ! alphaFunctionValue.compare(8, -1, "OUT" )) - { - animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_IN_OUT); - } - else if( ! alphaFunctionValue.compare(8, -1, "OUT_SINE" )) - { - animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_IN_OUT_SINE); - } - else if( ! alphaFunctionValue.compare(8, -1, "SINE" )) - { - animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_IN_SINE); - } - } - else if( ! alphaFunctionValue.compare( 5, 4, "OUT_" ) ) - { - if( ! alphaFunctionValue.compare(9, -1, "SQUARE" ) ) - { - animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_OUT_SQUARE); - } - else if( ! alphaFunctionValue.compare(9, -1, "SINE" ) ) - { - animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_OUT_SINE); - } - else if( ! alphaFunctionValue.compare(9, -1, "BACK" ) ) - { - animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_OUT_BACK); - } - } - } - else if( alphaFunctionValue == "REVERSE" ) - { - animator->alphaFunction = AlphaFunction(AlphaFunction::REVERSE); - } - else if( alphaFunctionValue == "BOUNCE" ) - { - animator->alphaFunction = AlphaFunction(AlphaFunction::BOUNCE); - } - else if( alphaFunctionValue == "SIN" ) - { - animator->alphaFunction = AlphaFunction(AlphaFunction::SIN); - } + ParseString(animator, value.Get< std::string >()); } else { -- 2.7.4