// Enables the text input.
controller->EnableTextInput( decorator );
+ // Set the placeholder text.
+ controller->SetPlaceholderText( Controller::PLACEHOLDER_TYPE_INACTIVE, "Hello Dali" );
+
// Creates an ImfManager.
ImfManager imfManager = ImfManager::Get();
+ // For coverage.
+ imfEvent = ImfManager::ImfEventData( ImfManager::GETSURROUNDING, "", 0, 0 );
+ controller->OnImfEvent( imfManager, imfEvent );
+
// Send VOID event.
imfEvent = ImfManager::ImfEventData( ImfManager::VOID, "", 0, 0 );
controller->OnImfEvent( imfManager, imfEvent );
if( NULL != valueSet )
{
- if( valueGet.second.Get<std::string>() != valueSet->Get<std::string>() )
+ if( valueSet->GetType() == Dali::Property::STRING && ( valueGet.second.Get<std::string>() != valueSet->Get<std::string>() ) )
{
- tet_printf( " Value got : [%s], expected : [%s]", valueGet.second.Get<std::string>().c_str(), valueSet->Get<std::string>().c_str() );
+ tet_printf( "Value got : [%s], expected : [%s]", valueGet.second.Get<std::string>().c_str(), valueSet->Get<std::string>().c_str() );
+ return false;
+ }
+ else if( valueSet->GetType() == Dali::Property::BOOLEAN && ( valueGet.second.Get<bool>() != valueSet->Get<bool>() ) )
+ {
+ tet_printf( "Value got : [%d], expected : [%d]", valueGet.second.Get<bool>(), valueSet->Get<bool>() );
+ return false;
+ }
+ else if( valueSet->GetType() == Dali::Property::INTEGER && ( valueGet.second.Get<int>() != valueSet->Get<int>() ) )
+ {
+ tet_printf( "Value got : [%d], expected : [%d]", valueGet.second.Get<int>(), valueSet->Get<int>() );
+ return false;
+ }
+ else if( valueSet->GetType() == Dali::Property::FLOAT && ( valueGet.second.Get<float>() != valueSet->Get<float>() ) )
+ {
+ tet_printf( "Value got : [%f], expected : [%f]", valueGet.second.Get<float>(), valueSet->Get<float>() );
+ return false;
+ }
+ else if( valueSet->GetType() == Dali::Property::VECTOR2 && ( valueGet.second.Get<Vector2>() != valueSet->Get<Vector2>() ) )
+ {
+ Vector2 vector2Get = valueGet.second.Get<Vector2>();
+ Vector2 vector2Set = valueSet->Get<Vector2>();
+ tet_printf( "Value got : [%f, %f], expected : [%f, %f]", vector2Get.x, vector2Get.y, vector2Set.x, vector2Set.y );
+ return false;
+ }
+ else if( valueSet->GetType() == Dali::Property::VECTOR4 && ( valueGet.second.Get<Vector4>() != valueSet->Get<Vector4>() ) )
+ {
+ Vector4 vector4Get = valueGet.second.Get<Vector4>();
+ Vector4 vector4Set = valueSet->Get<Vector4>();
+ tet_printf( "Value got : [%f, %f, %f, %f], expected : [%f, %f, %f, %f]", vector4Get.r, vector4Get.g, vector4Get.b, vector4Get.a, vector4Set.r, vector4Set.g, vector4Set.b, vector4Set.a );
return false;
}
}
editor.SetProperty( TextEditor::Property::OUTLINE, outlineMapSet );
- outlineMapSet["color"] = "red";
- outlineMapSet["width"] = "2";
outlineMapGet = editor.GetProperty<Property::Map>( TextEditor::Property::OUTLINE );
DALI_TEST_EQUALS( outlineMapGet.Count(), outlineMapSet.Count(), TEST_LOCATION );
DALI_TEST_EQUALS( DaliTestCheckMaps( outlineMapGet, outlineMapSet ), true, TEST_LOCATION );
{
const KeyValuePair& valueGet = fontStyleMapGet.GetKeyValue( index );
- if( valueGet.first.type == Property::Key::STRING )
+ Property::Value* valueSet = NULL;
+ if ( valueGet.first.type == Property::Key::INDEX )
{
- Property::Value* valueSet = fontStyleMapSet.Find( valueGet.first.stringKey );
- if( NULL != valueSet )
+ valueSet = fontStyleMapSet.Find( valueGet.first.indexKey );
+ }
+ else
+ {
+ // Get Key is a string so searching Set Map for a string key
+ valueSet = fontStyleMapSet.Find( valueGet.first.stringKey );
+ }
+
+ if( NULL != valueSet )
+ {
+ if( valueSet->GetType() == Dali::Property::STRING && ( valueGet.second.Get<std::string>() != valueSet->Get<std::string>() ) )
{
- if( valueGet.second.Get<std::string>() != valueSet->Get<std::string>() )
- {
- tet_printf( " Value got : [%s], expected : [%s]", valueGet.second.Get<std::string>().c_str(), valueSet->Get<std::string>().c_str() );
- return false;
- }
+ tet_printf( "Value got : [%s], expected : [%s]", valueGet.second.Get<std::string>().c_str(), valueSet->Get<std::string>().c_str() );
+ return false;
}
- else
+ else if( valueSet->GetType() == Dali::Property::BOOLEAN && ( valueGet.second.Get<bool>() != valueSet->Get<bool>() ) )
{
- tet_printf( " The key %s doesn't exist.", valueGet.first.stringKey.c_str() );
+ tet_printf( "Value got : [%d], expected : [%d]", valueGet.second.Get<bool>(), valueSet->Get<bool>() );
+ return false;
+ }
+ else if( valueSet->GetType() == Dali::Property::INTEGER && ( valueGet.second.Get<int>() != valueSet->Get<int>() ) )
+ {
+ tet_printf( "Value got : [%d], expected : [%d]", valueGet.second.Get<int>(), valueSet->Get<int>() );
+ return false;
+ }
+ else if( valueSet->GetType() == Dali::Property::FLOAT && ( valueGet.second.Get<float>() != valueSet->Get<float>() ) )
+ {
+ tet_printf( "Value got : [%f], expected : [%f]", valueGet.second.Get<float>(), valueSet->Get<float>() );
+ return false;
+ }
+ else if( valueSet->GetType() == Dali::Property::VECTOR2 && ( valueGet.second.Get<Vector2>() != valueSet->Get<Vector2>() ) )
+ {
+ Vector2 vector2Get = valueGet.second.Get<Vector2>();
+ Vector2 vector2Set = valueSet->Get<Vector2>();
+ tet_printf( "Value got : [%f, %f], expected : [%f, %f]", vector2Get.x, vector2Get.y, vector2Set.x, vector2Set.y );
+ return false;
+ }
+ else if( valueSet->GetType() == Dali::Property::VECTOR4 && ( valueGet.second.Get<Vector4>() != valueSet->Get<Vector4>() ) )
+ {
+ Vector4 vector4Get = valueGet.second.Get<Vector4>();
+ Vector4 vector4Set = valueSet->Get<Vector4>();
+ tet_printf( "Value got : [%f, %f, %f, %f], expected : [%f, %f, %f, %f]", vector4Get.r, vector4Get.g, vector4Get.b, vector4Get.a, vector4Set.r, vector4Set.g, vector4Set.b, vector4Set.a );
return false;
}
}
else
{
- Property::Value* valueSet = fontStyleMapSet.Find( valueGet.first.indexKey );
- if( NULL != valueSet )
+ if ( valueGet.first.type == Property::Key::INDEX )
{
- if( valueGet.second.Get<int>() != valueSet->Get<int>() )
- {
- tet_printf( " Integer Value got : [%d], expected : [%d]", valueGet.second.Get<int>(), valueSet->Get<int>() );
- return false;
- }
+ tet_printf( " The key %d doesn't exist.", valueGet.first.indexKey );
}
else
{
- tet_printf( " The Int key %d doesn't exist.", valueGet.first.indexKey );
- return false;
+ tet_printf( " The key %s doesn't exist.", valueGet.first.stringKey.c_str() );
}
+ return false;
}
}
}
field.SetProperty( TextField::Property::OUTLINE, outlineMapSet );
- outlineMapSet["color"] = "red";
- outlineMapSet["width"] = "2";
outlineMapGet = field.GetProperty<Property::Map>( TextField::Property::OUTLINE );
DALI_TEST_EQUALS( outlineMapGet.Count(), outlineMapSet.Count(), TEST_LOCATION );
DALI_TEST_EQUALS( DaliTestCheckMaps( outlineMapGet, outlineMapSet ), true, TEST_LOCATION );
{
const KeyValuePair& valueGet = fontStyleMapGet.GetKeyValue( index );
- Property::Value* valueSet = fontStyleMapSet.Find( valueGet.first.stringKey );
+ Property::Value* valueSet = NULL;
+ if ( valueGet.first.type == Property::Key::INDEX )
+ {
+ valueSet = fontStyleMapSet.Find( valueGet.first.indexKey );
+ }
+ else
+ {
+ // Get Key is a string so searching Set Map for a string key
+ valueSet = fontStyleMapSet.Find( valueGet.first.stringKey );
+ }
+
if( NULL != valueSet )
{
- if( valueGet.second.Get<std::string>() != valueSet->Get<std::string>() )
+ if( valueSet->GetType() == Dali::Property::STRING && ( valueGet.second.Get<std::string>() != valueSet->Get<std::string>() ) )
+ {
+ tet_printf( "Value got : [%s], expected : [%s]", valueGet.second.Get<std::string>().c_str(), valueSet->Get<std::string>().c_str() );
+ return false;
+ }
+ else if( valueSet->GetType() == Dali::Property::BOOLEAN && ( valueGet.second.Get<bool>() != valueSet->Get<bool>() ) )
+ {
+ tet_printf( "Value got : [%d], expected : [%d]", valueGet.second.Get<bool>(), valueSet->Get<bool>() );
+ return false;
+ }
+ else if( valueSet->GetType() == Dali::Property::INTEGER && ( valueGet.second.Get<int>() != valueSet->Get<int>() ) )
+ {
+ tet_printf( "Value got : [%d], expected : [%d]", valueGet.second.Get<int>(), valueSet->Get<int>() );
+ return false;
+ }
+ else if( valueSet->GetType() == Dali::Property::FLOAT && ( valueGet.second.Get<float>() != valueSet->Get<float>() ) )
+ {
+ tet_printf( "Value got : [%f], expected : [%f]", valueGet.second.Get<float>(), valueSet->Get<float>() );
+ return false;
+ }
+ else if( valueSet->GetType() == Dali::Property::VECTOR2 && ( valueGet.second.Get<Vector2>() != valueSet->Get<Vector2>() ) )
+ {
+ Vector2 vector2Get = valueGet.second.Get<Vector2>();
+ Vector2 vector2Set = valueSet->Get<Vector2>();
+ tet_printf( "Value got : [%f, %f], expected : [%f, %f]", vector2Get.x, vector2Get.y, vector2Set.x, vector2Set.y );
+ return false;
+ }
+ else if( valueSet->GetType() == Dali::Property::VECTOR4 && ( valueGet.second.Get<Vector4>() != valueSet->Get<Vector4>() ) )
{
- tet_printf( " Value got : [%s], expected : [%s]", valueGet.second.Get<std::string>().c_str(), valueSet->Get<std::string>().c_str() );
+ Vector4 vector4Get = valueGet.second.Get<Vector4>();
+ Vector4 vector4Set = valueSet->Get<Vector4>();
+ tet_printf( "Value got : [%f, %f, %f, %f], expected : [%f, %f, %f, %f]", vector4Get.r, vector4Get.g, vector4Get.b, vector4Get.a, vector4Set.r, vector4Set.g, vector4Set.b, vector4Set.a );
return false;
}
}
else
{
- tet_printf( " The key %s doesn't exist.", valueGet.first.stringKey.c_str() );
+ if ( valueGet.first.type == Property::Key::INDEX )
+ {
+ tet_printf( " The key %d doesn't exist.", valueGet.first.indexKey );
+ }
+ else
+ {
+ tet_printf( " The key %s doesn't exist.", valueGet.first.stringKey.c_str() );
+ }
return false;
}
}
outlineMapSet["width"] = 2.0f;
label.SetProperty( TextLabel::Property::OUTLINE, outlineMapSet );
- outlineMapSet["color"] = "red";
- outlineMapSet["width"] = "2";
outlineMapGet = label.GetProperty<Property::Map>( TextLabel::Property::OUTLINE );
DALI_TEST_EQUALS( outlineMapGet.Count(), outlineMapSet.Count(), TEST_LOCATION );
DALI_TEST_EQUALS( DaliTestCheckMaps( outlineMapGet, outlineMapSet ), true, TEST_LOCATION );
tet_infoline(" UtcDaliToolkitTextlabelTextDirection");
TextLabel label = TextLabel::New();
+ DALI_TEST_EQUALS( label.GetProperty< int >( DevelTextLabel::Property::TEXT_DIRECTION ), static_cast< int >( Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT ), TEST_LOCATION );
+
label.SetProperty( TextLabel::Property::TEXT, "Hello world" );
label.SetProperty( TextLabel::Property::POINT_SIZE, 20 );
Stage::GetCurrent().Add( label );
- application.SendNotification();
- application.Render();
-
DALI_TEST_EQUALS( label.GetProperty< int >( DevelTextLabel::Property::TEXT_DIRECTION ), static_cast< int >( Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT ), TEST_LOCATION );
label.SetProperty( TextLabel::Property::TEXT, "ﻡﺮﺤﺑﺍ ﺏﺎﻠﻋﺎﻠﻣ ﻡﺮﺤﺑﺍ" );
- application.SendNotification();
- application.Render();
DALI_TEST_EQUALS( label.GetProperty< int >( DevelTextLabel::Property::TEXT_DIRECTION ), static_cast< int >( Toolkit::DevelText::TextDirection::RIGHT_TO_LEFT ), TEST_LOCATION );
END_TEST;
#include <dali-toolkit/devel-api/visual-factory/transition-data.h>
#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
#include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
+#include <dali-toolkit/devel-api/visuals/text-visual-properties-devel.h>
#include <dali-toolkit/devel-api/visuals/animated-gradient-visual-properties-devel.h>
#include <dali-toolkit/dali-toolkit.h>
{
const KeyValuePair& valueGet = fontStyleMapGet.GetKeyValue( index );
- Property::Value* valueSet = fontStyleMapSet.Find( valueGet.first.stringKey );
+ Property::Value* valueSet = NULL;
+ if ( valueGet.first.type == Property::Key::INDEX )
+ {
+ valueSet = fontStyleMapSet.Find( valueGet.first.indexKey );
+ }
+ else
+ {
+ // Get Key is a string so searching Set Map for a string key
+ valueSet = fontStyleMapSet.Find( valueGet.first.stringKey );
+ }
+
if( NULL != valueSet )
{
- if( valueGet.second.Get<std::string>() != valueSet->Get<std::string>() )
+ if( valueSet->GetType() == Dali::Property::STRING && ( valueGet.second.Get<std::string>() != valueSet->Get<std::string>() ) )
+ {
+ tet_printf( "Value got : [%s], expected : [%s]", valueGet.second.Get<std::string>().c_str(), valueSet->Get<std::string>().c_str() );
+ return false;
+ }
+ else if( valueSet->GetType() == Dali::Property::BOOLEAN && ( valueGet.second.Get<bool>() != valueSet->Get<bool>() ) )
+ {
+ tet_printf( "Value got : [%d], expected : [%d]", valueGet.second.Get<bool>(), valueSet->Get<bool>() );
+ return false;
+ }
+ else if( valueSet->GetType() == Dali::Property::INTEGER && ( valueGet.second.Get<int>() != valueSet->Get<int>() ) )
+ {
+ tet_printf( "Value got : [%d], expected : [%d]", valueGet.second.Get<int>(), valueSet->Get<int>() );
+ return false;
+ }
+ else if( valueSet->GetType() == Dali::Property::FLOAT && ( valueGet.second.Get<float>() != valueSet->Get<float>() ) )
{
- tet_printf( " Value got : [%s], expected : [%s]", valueGet.second.Get<std::string>().c_str(), valueSet->Get<std::string>().c_str() );
+ tet_printf( "Value got : [%f], expected : [%f]", valueGet.second.Get<float>(), valueSet->Get<float>() );
+ return false;
+ }
+ else if( valueSet->GetType() == Dali::Property::VECTOR2 && ( valueGet.second.Get<Vector2>() != valueSet->Get<Vector2>() ) )
+ {
+ Vector2 vector2Get = valueGet.second.Get<Vector2>();
+ Vector2 vector2Set = valueSet->Get<Vector2>();
+ tet_printf( "Value got : [%f, %f], expected : [%f, %f]", vector2Get.x, vector2Get.y, vector2Set.x, vector2Set.y );
+ return false;
+ }
+ else if( valueSet->GetType() == Dali::Property::VECTOR4 && ( valueGet.second.Get<Vector4>() != valueSet->Get<Vector4>() ) )
+ {
+ Vector4 vector4Get = valueGet.second.Get<Vector4>();
+ Vector4 vector4Set = valueSet->Get<Vector4>();
+ tet_printf( "Value got : [%f, %f, %f, %f], expected : [%f, %f, %f, %f]", vector4Get.r, vector4Get.g, vector4Get.b, vector4Get.a, vector4Set.r, vector4Set.g, vector4Set.b, vector4Set.a );
return false;
}
}
else
{
- tet_printf( " The key %s doesn't exist.", valueGet.first.stringKey.c_str() );
+ if ( valueGet.first.type == Property::Key::INDEX )
+ {
+ tet_printf( " The key %d doesn't exist.", valueGet.first.indexKey );
+ }
+ else
+ {
+ tet_printf( " The key %s doesn't exist.", valueGet.first.stringKey.c_str() );
+ }
return false;
}
}
propertyMap.Insert( "horizontalAlignment", "CENTER" );
propertyMap.Insert( "verticalAlignment", "CENTER" );
propertyMap.Insert( "textColor", Color::RED );
+
+ Property::Map shadowMapSet;
+ propertyMap.Insert( "shadow", shadowMapSet.Add("color", Color::RED).Add("offset", Vector2(2.0f, 2.0f)).Add("blurRadius", 3.0f) );
+
+ Property::Map underlineMapSet;
+ propertyMap.Insert( "underline", underlineMapSet.Add("enable", "true").Add("color", "green").Add("height", "1") );
+
+ Property::Map outlineMapSet;
+ propertyMap.Insert( "outline", outlineMapSet.Add("color", Color::YELLOW).Add("width", 1) );
+
Visual::Base textVisual = factory.CreateVisual( propertyMap );
Property::Map resultMap;
DALI_TEST_CHECK( value );
DALI_TEST_CHECK( !value->Get<bool>() );
+ value = resultMap.Find( TextVisual::Property::SHADOW, Property::MAP );
+ DALI_TEST_CHECK( value );
+
+ Property::Map shadowMapGet = value->Get<Property::Map>();
+ DALI_TEST_EQUALS( shadowMapGet.Count(), shadowMapSet.Count(), TEST_LOCATION );
+ DALI_TEST_EQUALS( DaliTestCheckMaps( shadowMapGet, shadowMapSet ), true, TEST_LOCATION );
+
+ value = resultMap.Find( TextVisual::Property::UNDERLINE, Property::MAP );
+ DALI_TEST_CHECK( value );
+
+ Property::Map underlineMapGet = value->Get<Property::Map>();
+ DALI_TEST_EQUALS( underlineMapGet.Count(), underlineMapSet.Count(), TEST_LOCATION );
+ DALI_TEST_EQUALS( DaliTestCheckMaps( underlineMapGet, underlineMapSet ), true, TEST_LOCATION );
+
+ value = resultMap.Find( DevelTextVisual::Property::OUTLINE, Property::MAP );
+ DALI_TEST_CHECK( value );
+
+ Property::Map outlineMapGet = value->Get<Property::Map>();
+ DALI_TEST_EQUALS( outlineMapGet.Count(), outlineMapSet.Count(), TEST_LOCATION );
+ DALI_TEST_EQUALS( DaliTestCheckMaps( outlineMapGet, outlineMapSet ), true, TEST_LOCATION );
+
END_TEST;
}
ALIASES += SINCE_1_2_14="@since 1.2.14"
ALIASES += SINCE_1_2_32="@since 1.2.32"
+# Extra tags for Tizen 4.0
+ALIASES += SINCE_1_3_4="@since 1.3.4"
+
ALIASES += DEPRECATED_1_0="@deprecated Deprecated since 1.0"
ALIASES += DEPRECATED_1_1="@deprecated Deprecated since 1.1"
ALIASES += DEPRECATED_1_2_8="@deprecated Deprecated since 1.2.8"
#ALIASES += SINCE_1_2_14="\par Since:\n 3.0, DALi version 1.2.14"
#ALIASES += SINCE_1_2_32="\par Since:\n 3.0, DALi version 1.2.32"
+## Extra tags for Tizen 4.0
+#ALIASES += SINCE_1_3_4="\par Since:\n 4.0, DALi version 1.3.4"
+
## DALi has no deprecated API in Tizen 2.4 because it's DALi's first release.
## Thus deprecated APIs in DALi 1.0.xx will be deprecated in Tizen 3.0.
#ALIASES += DEPRECATED_1_0="@deprecated Deprecated since 3.0, DALi version 1.0"
$(devel_api_src_dir)/visuals/image-visual-properties-devel.h \
$(devel_api_src_dir)/visuals/image-visual-actions-devel.h \
$(devel_api_src_dir)/visuals/animated-gradient-visual-properties-devel.h \
+ $(devel_api_src_dir)/visuals/text-visual-properties-devel.h \
$(devel_api_src_dir)/visuals/visual-properties-devel.h
devel_api_shadow_view_header_files = \
--- /dev/null
+#ifndef DALI_TOOLKIT_DEVEL_API_VISUALS_TEXT_VISUAL_PROPERTIES_DEVEL_H
+#define DALI_TOOLKIT_DEVEL_API_VISUALS_TEXT_VISUAL_PROPERTIES_DEVEL_H
+
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/visuals/text-visual-properties.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace DevelTextVisual
+{
+
+namespace Property
+{
+
+/**
+ * @brief All the visual types.
+ */
+enum
+{
+ TEXT = Dali::Toolkit::TextVisual::Property::TEXT,
+ FONT_FAMILY = Dali::Toolkit::TextVisual::Property::FONT_FAMILY,
+ FONT_STYLE = Dali::Toolkit::TextVisual::Property::FONT_STYLE,
+ POINT_SIZE = Dali::Toolkit::TextVisual::Property::POINT_SIZE,
+ MULTI_LINE = Dali::Toolkit::TextVisual::Property::MULTI_LINE,
+ HORIZONTAL_ALIGNMENT = Dali::Toolkit::TextVisual::Property::HORIZONTAL_ALIGNMENT,
+ VERTICAL_ALIGNMENT = Dali::Toolkit::TextVisual::Property::VERTICAL_ALIGNMENT,
+ TEXT_COLOR = Dali::Toolkit::TextVisual::Property::TEXT_COLOR,
+ ENABLE_MARKUP = Dali::Toolkit::TextVisual::Property::ENABLE_MARKUP,
+ SHADOW = Dali::Toolkit::TextVisual::Property::SHADOW,
+ UNDERLINE = Dali::Toolkit::TextVisual::Property::UNDERLINE,
+
+ /**
+ * @brief The default outline parameters.
+ * @details name "outline", type Property::MAP.
+ */
+ OUTLINE = UNDERLINE + 1
+};
+
+
+} // namespace Property
+
+} // namespace DevelTextVisual
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_DEVEL_API_VISUALS_TEXT_VISUAL_PROPERTIES_DEVEL_H
mBoundingBox(),
mHighlightColor( LIGHT_BLUE ),
mHighlightPosition( Vector2::ZERO ),
+ mHighlightSize( Vector2::ZERO ),
+ mControlSize( Vector2::ZERO ),
+ mHighlightOutlineOffset( 0.f ),
mActiveCursor( ACTIVE_CURSOR_NONE ),
mCursorBlinkInterval( CURSOR_BLINK_INTERVAL ),
mCursorBlinkDuration( 0.0f ),
if ( mHighlightActor )
{
// Sets the position of the highlight actor inside the decorator.
- mHighlightActor.SetPosition( mHighlightPosition.x,
- mHighlightPosition.y );
+ mHighlightActor.SetPosition( mHighlightPosition.x + mHighlightOutlineOffset,
+ mHighlightPosition.y + mHighlightOutlineOffset );
const unsigned int numberOfQuads = mHighlightQuadList.Count();
if( 0u != numberOfQuads )
Vector2 mHighlightPosition; ///< The position of the highlight actor.
Size mHighlightSize; ///< The size of the highlighted text.
Size mControlSize; ///< The control's size. Set by the Relayout.
+ float mHighlightOutlineOffset; ///< The outline's offset.
unsigned int mActiveCursor;
unsigned int mCursorBlinkInterval;
*( mImpl->mHighlightQuadList.Begin() + index ) = quad;
}
-void Decorator::SetHighLightBox( const Vector2& position, const Size& size )
+void Decorator::SetHighLightBox( const Vector2& position, const Size& size, float outlineOffset )
{
mImpl->mHighlightPosition = position;
mImpl->mHighlightSize = size;
+ mImpl->mHighlightOutlineOffset = outlineOffset;
}
void Decorator::ClearHighlights()
{
mImpl->mHighlightQuadList.Clear();
mImpl->mHighlightPosition = Vector2::ZERO;
+ mImpl->mHighlightOutlineOffset = 0.f;
}
void Decorator::ResizeHighlightQuads( unsigned int numberOfQuads )
*
* @param[in] position The position of the highlighted text in decorator's coords.
* @param[in] size The size of the highlighted text.
+ * @param[in] outlineOffset The outline's offset.
*/
void SetHighLightBox( const Vector2& position,
- const Size& size );
+ const Size& size,
+ float outlineOffset );
/**
* @brief Removes all of the previously added highlights.
floatStr = ss.str();
}
+void UintToString( unsigned int value, std::string& uIntStr )
+{
+ std::stringstream ss;
+ ss << value;
+ uIntStr = ss.str();
+}
+
void UintColorToVector4( unsigned int color, Vector4& retColor )
{
retColor.a = static_cast<float>( ( color & 0xFF000000 ) >> 24u ) / 255.f;
void FloatToString( float value, std::string& floatStr );
/**
+ * @brief Converts an unsigned int into a string.
+ *
+ * @param[in] value The unsigned int value.
+ * @param[out] uIntStr The string.
+ */
+void UintToString( unsigned int value, std::string& uIntStr );
+
+/**
* @brief Converts an ARGB color packed in 4 byte unsigned int into a Vector4 color used in Dali.
*
* @param[in] color An ARGB color packed in an unsigned int.
}
void AtlasGlyphManager::Add( const Text::GlyphInfo& glyph,
+ const uint32_t outlineWidth,
const PixelData& bitmap,
Dali::Toolkit::AtlasManager::AtlasSlot& slot )
{
GlyphRecordEntry record;
record.mIndex = glyph.index;
+ record.mOutlineWidth = outlineWidth;
record.mImageId = slot.mImageId;
record.mCount = 1;
bool AtlasGlyphManager::IsCached( Text::FontId fontId,
Text::GlyphIndex index,
+ uint32_t outlineWidth,
Dali::Toolkit::AtlasManager::AtlasSlot& slot )
{
for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
++glyphRecordIt )
{
- if ( glyphRecordIt->mIndex == index )
+ if ( glyphRecordIt->mIndex == index && glyphRecordIt->mOutlineWidth == outlineWidth )
{
slot.mImageId = glyphRecordIt->mImageId;
slot.mAtlasId = mAtlasManager.GetAtlas( slot.mImageId );
return mMetrics;
}
-void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, int32_t delta )
+void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, uint32_t outlineWidth, int32_t delta )
{
if( 0 != delta )
{
glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
++glyphRecordIt )
{
- if ( glyphRecordIt->mIndex == index )
+ if ( glyphRecordIt->mIndex == index && glyphRecordIt->mOutlineWidth == outlineWidth )
{
glyphRecordIt->mCount += delta;
DALI_ASSERT_DEBUG( glyphRecordIt->mCount >= 0 && "Glyph ref-count should not be negative" );
struct GlyphRecordEntry
{
Text::GlyphIndex mIndex;
+ uint32_t mOutlineWidth;
uint32_t mImageId;
int32_t mCount;
};
* @copydoc Toolkit::AtlasGlyphManager::Add
*/
void Add( const Text::GlyphInfo& glyph,
+ const uint32_t outlineWidth,
const PixelData& bitmap,
Dali::Toolkit::AtlasManager::AtlasSlot& slot );
*/
bool IsCached( Text::FontId fontId,
Text::GlyphIndex index,
+ uint32_t outlineWidth,
Dali::Toolkit::AtlasManager::AtlasSlot& slot );
/**
/**
* @copydoc toolkit::AtlasGlyphManager::AdjustReferenceCount
*/
- void AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, int32_t delta );
+ void AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, uint32_t outlineWidth, int32_t delta );
/**
* @copydoc Toolkit::AtlasGlyphManager::GetTextures
}
void AtlasGlyphManager::Add( const Text::GlyphInfo& glyph,
+ const uint32_t outlineWidth,
const PixelData& bitmap,
AtlasManager::AtlasSlot& slot )
{
- GetImplementation(*this).Add( glyph, bitmap, slot );
+ GetImplementation(*this).Add( glyph, outlineWidth, bitmap, slot );
}
void AtlasGlyphManager::GenerateMeshData( uint32_t imageId,
bool AtlasGlyphManager::IsCached( Text::FontId fontId,
Text::GlyphIndex index,
+ uint32_t outlineWidth,
AtlasManager::AtlasSlot& slot )
{
- return GetImplementation(*this).IsCached( fontId, index, slot );
+ return GetImplementation(*this).IsCached( fontId, index, outlineWidth, slot );
}
void AtlasGlyphManager::SetNewAtlasSize( uint32_t width, uint32_t height, uint32_t blockWidth, uint32_t blockHeight )
return GetImplementation(*this).GetMetrics();
}
-void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, int32_t delta )
+void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, uint32_t outlineWidth, int32_t delta )
{
- GetImplementation(*this).AdjustReferenceCount( fontId, index, delta );
+ GetImplementation(*this).AdjustReferenceCount( fontId, index, outlineWidth, delta );
}
} // namespace Toolkit
* @brief Ask Atlas Manager to add a glyph
*
* @param[in] glyph glyph to add to an atlas
+ * @param[in] outlineWidth the outline width of the glyph
* @param[in] bitmap bitmap to use for glyph addition
* @param[out] slot information returned by atlas manager for addition
*/
void Add( const Text::GlyphInfo& glyph,
+ const uint32_t outlineWidth,
const PixelData& bitmap,
AtlasManager::AtlasSlot& slot );
*
* @param[in] fontId The font that this glyph comes from
* @param[in] index The GlyphIndex of this glyph
+ * @param[in] outlineWidth The outline width of this glyph
* @param[out] slot container holding information about the glyph( mImage = 0 indicates not being cached )
*
* @return Whether glyph is cached or not ?
*/
bool IsCached( Text::FontId fontId,
Text::GlyphIndex index,
+ uint32_t outlineWidth,
AtlasManager::AtlasSlot& slot );
/**
*
* @param[in] fontId The font this image came from
* @param[in] index The index of the glyph
+ * @param[in] outlineWidth The outline width of the glyph
* @param[in] delta The adjustment to make to the reference count
*/
- void AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, int32_t delta );
+ void AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, uint32_t outlineWidth, int32_t delta );
private:
const float ONE( 1.0f );
const uint32_t DEFAULT_ATLAS_WIDTH = 512u;
const uint32_t DEFAULT_ATLAS_HEIGHT = 512u;
-const int NO_OUTLINE( 0 );
+const uint32_t NO_OUTLINE = 0;
}
struct AtlasRenderer::Impl
TextCacheEntry()
: mFontId( 0 ),
mIndex( 0 ),
+ mOutlineWidth( 0 ),
mImageId( 0 )
{
}
FontId mFontId;
Text::GlyphIndex mIndex;
+ uint32_t mOutlineWidth;
uint32_t mImageId;
};
return false;
}
+ void CacheGlyph( const GlyphInfo& glyph, FontId lastFontId, uint32_t outline, AtlasManager::AtlasSlot& slot )
+ {
+ const bool glyphNotCached = !mGlyphManager.IsCached( glyph.fontId, glyph.index, outline, slot ); // Check FontGlyphRecord vector for entry with glyph index and fontId
+
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "AddGlyphs fontID[%u] glyphIndex[%u] [%s]\n", glyph.fontId, glyph.index, (glyphNotCached)?"not cached":"cached" );
+
+ if( glyphNotCached )
+ {
+ MaxBlockSize& blockSize = mBlockSizes[0u];
+
+ if ( lastFontId != glyph.fontId )
+ {
+ uint32_t index = 0u;
+ // Looks through all stored block sizes until finds the one which mataches required glyph font it. Ensures new atlas block size will match existing for same font id.
+ // CalculateBlocksSize() above ensures a block size entry exists.
+ for( std::vector<MaxBlockSize>::const_iterator it = mBlockSizes.begin(),
+ endIt = mBlockSizes.end();
+ it != endIt;
+ ++it, ++index )
+ {
+ const MaxBlockSize& blockSizeEntry = *it;
+ if( blockSizeEntry.mFontId == glyph.fontId )
+ {
+ blockSize = mBlockSizes[index];
+ }
+ }
+ }
+
+ // Create a new image for the glyph
+ PixelData bitmap;
+
+ // Whether the glyph is an outline.
+ const bool isOutline = 0u != outline;
+
+ // Whether the current glyph is a color one.
+ const bool isColorGlyph = mFontClient.IsColorGlyph( glyph.fontId, glyph.index );
+
+ if( !isOutline || ( isOutline && !isColorGlyph) )
+ {
+ // Retrieve the emoji's bitmap.
+ TextAbstraction::FontClient::GlyphBufferData glyphBufferData;
+ glyphBufferData.width = isColorGlyph ? glyph.width : 0; // Desired width and height.
+ glyphBufferData.height = isColorGlyph ? glyph.height : 0;
+
+ mFontClient.CreateBitmap( glyph.fontId,
+ glyph.index,
+ glyphBufferData,
+ outline );
+
+ // Create the pixel data.
+ bitmap = PixelData::New( glyphBufferData.buffer,
+ glyphBufferData.width * glyphBufferData.height * GetBytesPerPixel( glyphBufferData.format ),
+ glyphBufferData.width,
+ glyphBufferData.height,
+ glyphBufferData.format,
+ PixelData::DELETE_ARRAY );
+
+ if( bitmap )
+ {
+ // Ensure that the next image will fit into the current block size
+ if( bitmap.GetWidth() > blockSize.mNeededBlockWidth )
+ {
+ blockSize.mNeededBlockWidth = bitmap.GetWidth();
+ }
+
+ if( bitmap.GetHeight() > blockSize.mNeededBlockHeight )
+ {
+ blockSize.mNeededBlockHeight = bitmap.GetHeight();
+ }
+
+ // If CheckAtlas in AtlasManager::Add can't fit the bitmap in the current atlas it will create a new atlas
+
+ // Setting the block size and size of new atlas does not mean a new one will be created. An existing atlas may still surffice.
+ mGlyphManager.SetNewAtlasSize( DEFAULT_ATLAS_WIDTH,
+ DEFAULT_ATLAS_HEIGHT,
+ blockSize.mNeededBlockWidth,
+ blockSize.mNeededBlockHeight );
+
+ // Locate a new slot for our glyph
+ mGlyphManager.Add( glyph, outline, bitmap, slot ); // slot will be 0 is glyph not added
+ }
+ }
+ }
+ else
+ {
+ // We have 2+ copies of the same glyph
+ mGlyphManager.AdjustReferenceCount( glyph.fontId, glyph.index, outline, 1 ); //increment
+ }
+ }
+
+ void GenerateMesh( const GlyphInfo& glyph,
+ const Vector2& position,
+ const Vector4& color,
+ uint32_t outline,
+ AtlasManager::AtlasSlot& slot,
+ bool underlineGlyph,
+ float currentUnderlinePosition,
+ float currentUnderlineThickness,
+ std::vector<MeshRecord>& meshContainer,
+ Vector<TextCacheEntry>& newTextCache,
+ Vector<Extent>& extents )
+ {
+ // Generate mesh data for this quad, plugging in our supplied position
+ AtlasManager::Mesh2D newMesh;
+ mGlyphManager.GenerateMeshData( slot.mImageId, position, newMesh );
+
+ TextCacheEntry textCacheEntry;
+ textCacheEntry.mFontId = glyph.fontId;
+ textCacheEntry.mImageId = slot.mImageId;
+ textCacheEntry.mIndex = glyph.index;
+ textCacheEntry.mOutlineWidth = outline;
+
+ newTextCache.PushBack( textCacheEntry );
+
+ AtlasManager::Vertex2D* verticesBuffer = newMesh.mVertices.Begin();
+
+ for( unsigned int index = 0u, size = newMesh.mVertices.Count();
+ index < size;
+ ++index )
+ {
+ AtlasManager::Vertex2D& vertex = *( verticesBuffer + index );
+
+ // Set the color of the vertex.
+ vertex.mColor = color;
+ }
+
+ // Find an existing mesh data object to attach to ( or create a new one, if we can't find one using the same atlas)
+ StitchTextMesh( meshContainer,
+ newMesh,
+ extents,
+ position.y + glyph.yBearing,
+ underlineGlyph,
+ currentUnderlinePosition,
+ currentUnderlineThickness,
+ slot );
+ }
+
+ void CreateActors( const std::vector<MeshRecord>& meshContainer,
+ const Size& textSize,
+ const Vector4& color,
+ const Vector4& shadowColor,
+ const Vector2& shadowOffset,
+ Actor textControl,
+ Property::Index animatablePropertyIndex,
+ bool drawShadow )
+ {
+ if( !mActor )
+ {
+ // Create a container actor to act as a common parent for text and shadow, to avoid color inheritence issues.
+ mActor = Actor::New();
+ mActor.SetParentOrigin( ParentOrigin::TOP_LEFT );
+ mActor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+ mActor.SetSize( textSize );
+ mActor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
+ }
+
+ for( std::vector< MeshRecord >::const_iterator it = meshContainer.begin(),
+ endIt = meshContainer.end();
+ it != endIt; ++it )
+ {
+ const MeshRecord& meshRecord = *it;
+
+ Actor actor = CreateMeshActor( textControl, animatablePropertyIndex, color, meshRecord, textSize, STYLE_NORMAL );
+
+ // Whether the actor has renderers.
+ const bool hasRenderer = actor.GetRendererCount() > 0u;
+
+ // Create an effect if necessary
+ if( hasRenderer &&
+ drawShadow )
+ {
+ // Change the color of the vertices.
+ for( Vector<AtlasManager::Vertex2D>::Iterator vIt = meshRecord.mMesh.mVertices.Begin(),
+ vEndIt = meshRecord.mMesh.mVertices.End();
+ vIt != vEndIt;
+ ++vIt )
+ {
+ AtlasManager::Vertex2D& vertex = *vIt;
+
+ vertex.mColor = shadowColor;
+ }
+
+ Actor shadowActor = CreateMeshActor(textControl, animatablePropertyIndex, color, meshRecord, textSize, STYLE_DROP_SHADOW );
+#if defined(DEBUG_ENABLED)
+ shadowActor.SetName( "Text Shadow renderable actor" );
+#endif
+ // Offset shadow in x and y
+ shadowActor.RegisterProperty("uOffset", shadowOffset );
+ Dali::Renderer renderer( shadowActor.GetRendererAt( 0 ) );
+ int depthIndex = renderer.GetProperty<int>(Dali::Renderer::Property::DEPTH_INDEX);
+ renderer.SetProperty( Dali::Renderer::Property::DEPTH_INDEX, depthIndex - 1 );
+ mActor.Add( shadowActor );
+ }
+
+ if( hasRenderer )
+ {
+ mActor.Add( actor );
+ }
+ }
+ }
+
void AddGlyphs( Text::ViewInterface& view,
Actor textControl,
Property::Index animatablePropertyIndex,
float minLineOffset )
{
AtlasManager::AtlasSlot slot;
+ slot.mImageId = 0u;
+ slot.mAtlasId = 0u;
+
+ AtlasManager::AtlasSlot slotOutline;
+ slotOutline.mImageId = 0u;
+ slotOutline.mAtlasId = 0u;
+
std::vector< MeshRecord > meshContainer;
+ std::vector< MeshRecord > meshContainerOutline;
Vector< Extent > extents;
- TextCacheEntry textCacheEntry;
mDepth = depth;
const Vector2& textSize( view.GetLayoutSize() );
const Vector2 halfTextSize( textSize * 0.5f );
const Vector2& shadowOffset( view.GetShadowOffset() );
const Vector4& shadowColor( view.GetShadowColor() );
- const bool underlineEnabled( view.IsUnderlineEnabled() );
+ const bool underlineEnabled = view.IsUnderlineEnabled();
const Vector4& underlineColor( view.GetUnderlineColor() );
- const float underlineHeight( view.GetUnderlineHeight() );
+ const float underlineHeight = view.GetUnderlineHeight();
+ const unsigned int outlineWidth = view.GetOutlineWidth();
+ const Vector4& outlineColor( view.GetOutlineColor() );
+ const bool isOutline = 0u != outlineWidth;
const bool useDefaultColor = ( NULL == colorsBuffer );
float currentUnderlinePosition = ZERO;
float currentUnderlineThickness = underlineHeight;
- uint32_t currentBlockSize = 0;
FontId lastFontId = 0;
FontId lastUnderlinedFontId = 0;
Style style = STYLE_NORMAL;
for( uint32_t i = 0, glyphSize = glyphs.Size(); i < glyphSize; ++i )
{
const GlyphInfo& glyph = *( glyphsBuffer + i );
- const bool underlineGlyph = underlineEnabled || IsGlyphUnderlined( i, underlineRuns );
- thereAreUnderlinedGlyphs = thereAreUnderlinedGlyphs || underlineGlyph;
+ const bool isGlyphUnderlined = underlineEnabled || IsGlyphUnderlined( i, underlineRuns );
+ thereAreUnderlinedGlyphs = thereAreUnderlinedGlyphs || isGlyphUnderlined;
// No operation for white space
if( glyph.width && glyph.height )
{
// Are we still using the same fontId as previous
- if( underlineGlyph && ( glyph.fontId != lastUnderlinedFontId ) )
+ if( isGlyphUnderlined && ( glyph.fontId != lastUnderlinedFontId ) )
{
// We need to fetch fresh font underline metrics
FontMetrics fontMetrics;
lastUnderlinedFontId = glyph.fontId;
} // underline
- bool glyphNotCached = !mGlyphManager.IsCached( glyph.fontId, glyph.index, slot ); // Check FontGlyphRecord vector for entry with glyph index and fontId
-
- DALI_LOG_INFO( gLogFilter, Debug::Verbose, "AddGlyphs fontID[%u] glyphIndex[%u] [%s]\n", glyph.fontId, glyph.index, (glyphNotCached)?"not cached":"cached" );
+ // Retrieves and caches the glyph's bitmap.
+ CacheGlyph( glyph, lastFontId, NO_OUTLINE, slot );
- if( glyphNotCached )
+ // Retrieves and caches the outline glyph's bitmap.
+ if( isOutline )
{
- MaxBlockSize& blockSize = mBlockSizes[currentBlockSize];
-
- if ( lastFontId != glyph.fontId )
- {
- uint32_t index = 0u;
- // Looks through all stored block sizes until finds the one which mataches required glyph font it. Ensures new atlas block size will match existing for same font id.
- // CalculateBlocksSize() above ensures a block size entry exists.
- for( std::vector<MaxBlockSize>::const_iterator it = mBlockSizes.begin(),
- endIt = mBlockSizes.end();
- it != endIt;
- ++it, ++index )
- {
- const MaxBlockSize& blockSizeEntry = *it;
- if( blockSizeEntry.mFontId == glyph.fontId )
- {
- blockSize = mBlockSizes[index];
- }
- }
- }
-
- // Create a new image for the glyph
- PixelData bitmap;
-
- // Whether the current glyph is a color one.
- const bool isColorGlyph = mFontClient.IsColorGlyph( glyph.fontId, glyph.index );
-
- // Retrieve the emoji's bitmap.
- TextAbstraction::FontClient::GlyphBufferData glyphBufferData;
- glyphBufferData.width = isColorGlyph ? glyph.width : 0; // Desired width and height.
- glyphBufferData.height = isColorGlyph ? glyph.height : 0;
-
- mFontClient.CreateBitmap( glyph.fontId,
- glyph.index,
- glyphBufferData,
- NO_OUTLINE );
-
- // Create the pixel data.
- bitmap = PixelData::New( glyphBufferData.buffer,
- glyph.width * glyph.height * GetBytesPerPixel( glyphBufferData.format ),
- glyph.width,
- glyph.height,
- glyphBufferData.format,
- PixelData::DELETE_ARRAY );
-
- if( bitmap )
- {
- // Ensure that the next image will fit into the current block size
- if( bitmap.GetWidth() > blockSize.mNeededBlockWidth )
- {
- blockSize.mNeededBlockWidth = bitmap.GetWidth();
- }
-
- if( bitmap.GetHeight() > blockSize.mNeededBlockHeight )
- {
- blockSize.mNeededBlockHeight = bitmap.GetHeight();
- }
-
- // If CheckAtlas in AtlasManager::Add can't fit the bitmap in the current atlas it will create a new atlas
-
- // Setting the block size and size of new atlas does not mean a new one will be created. An existing atlas may still surffice.
- mGlyphManager.SetNewAtlasSize( DEFAULT_ATLAS_WIDTH,
- DEFAULT_ATLAS_HEIGHT,
- blockSize.mNeededBlockWidth,
- blockSize.mNeededBlockHeight );
-
- // Locate a new slot for our glyph
- mGlyphManager.Add( glyph, bitmap, slot ); // slot will be 0 is glyph not added
- }
- }
- else
- {
- // We have 2+ copies of the same glyph
- mGlyphManager.AdjustReferenceCount( glyph.fontId, glyph.index, 1/*increment*/ );
+ CacheGlyph( glyph, lastFontId, outlineWidth, slotOutline );
}
// Move the origin (0,0) of the mesh to the center of the actor
if ( 0u != slot.mImageId ) // invalid slot id, glyph has failed to be added to atlas
{
- // Generate mesh data for this quad, plugging in our supplied position
- AtlasManager::Mesh2D newMesh;
- mGlyphManager.GenerateMeshData( slot.mImageId, position, newMesh );
- textCacheEntry.mFontId = glyph.fontId;
- textCacheEntry.mImageId = slot.mImageId;
- textCacheEntry.mIndex = glyph.index;
- newTextCache.PushBack( textCacheEntry );
-
- AtlasManager::Vertex2D* verticesBuffer = newMesh.mVertices.Begin();
+ Vector2 positionPlusOutlineOffset = position;
+ if( isOutline )
+ {
+ // Add an offset to the text.
+ const float outlineWidthOffset = static_cast<float>( outlineWidth );
+ positionPlusOutlineOffset += Vector2( outlineWidthOffset, outlineWidthOffset );
+ }
// Get the color of the character.
const ColorIndex colorIndex = useDefaultColor ? 0u : *( colorIndicesBuffer + i );
const Vector4& color = ( useDefaultColor || ( 0u == colorIndex ) ) ? defaultColor : *( colorsBuffer + colorIndex - 1u );
- for( unsigned int index = 0u, size = newMesh.mVertices.Count();
- index < size;
- ++index )
- {
- AtlasManager::Vertex2D& vertex = *( verticesBuffer + index );
-
- // Set the color of the vertex.
- vertex.mColor = color;
- }
-
- // Find an existing mesh data object to attach to ( or create a new one, if we can't find one using the same atlas)
- StitchTextMesh( meshContainer,
- newMesh,
- extents,
- position.y + glyph.yBearing,
- underlineGlyph,
- currentUnderlinePosition,
- currentUnderlineThickness,
- slot );
+ GenerateMesh( glyph,
+ positionPlusOutlineOffset,
+ color,
+ NO_OUTLINE,
+ slot,
+ isGlyphUnderlined,
+ currentUnderlinePosition,
+ currentUnderlineThickness,
+ meshContainer,
+ newTextCache,
+ extents);
lastFontId = glyph.fontId; // Prevents searching for existing blocksizes when string of the same fontId.
}
+
+ if( isOutline && ( 0u != slotOutline.mImageId ) ) // invalid slot id, glyph has failed to be added to atlas
+ {
+ GenerateMesh( glyph,
+ position,
+ outlineColor,
+ outlineWidth,
+ slotOutline,
+ false,
+ currentUnderlinePosition,
+ currentUnderlineThickness,
+ meshContainerOutline,
+ newTextCache,
+ extents);
+ }
}
} // glyphs
}
// For each MeshData object, create a mesh actor and add to the renderable actor
- if( !meshContainer.empty() )
+ bool isShadowDrawn = false;
+ if( !meshContainerOutline.empty() )
{
- if( !mActor )
- {
- // Create a container actor to act as a common parent for text and shadow, to avoid color inheritence issues.
- mActor = Actor::New();
- mActor.SetParentOrigin( ParentOrigin::TOP_LEFT );
- mActor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
- mActor.SetSize( textSize );
- mActor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
- }
-
- for( std::vector< MeshRecord >::iterator it = meshContainer.begin(),
- endIt = meshContainer.end();
- it != endIt; ++it )
- {
- MeshRecord& meshRecord = *it;
-
- Actor actor = CreateMeshActor( textControl, animatablePropertyIndex, defaultColor, meshRecord, textSize, STYLE_NORMAL );
-
- // Whether the actor has renderers.
- const bool hasRenderer = actor.GetRendererCount() > 0u;
-
- // Create an effect if necessary
- if( hasRenderer &&
- ( style == STYLE_DROP_SHADOW ) )
- {
- // Change the color of the vertices.
- for( Vector<AtlasManager::Vertex2D>::Iterator vIt = meshRecord.mMesh.mVertices.Begin(),
- vEndIt = meshRecord.mMesh.mVertices.End();
- vIt != vEndIt;
- ++vIt )
- {
- AtlasManager::Vertex2D& vertex = *vIt;
-
- vertex.mColor = shadowColor;
- }
-
- Actor shadowActor = CreateMeshActor(textControl, animatablePropertyIndex, defaultColor, meshRecord, textSize, STYLE_DROP_SHADOW );
-#if defined(DEBUG_ENABLED)
- shadowActor.SetName( "Text Shadow renderable actor" );
-#endif
- // Offset shadow in x and y
- shadowActor.RegisterProperty("uOffset", shadowOffset );
- Dali::Renderer renderer( shadowActor.GetRendererAt( 0 ) );
- int depthIndex = renderer.GetProperty<int>(Dali::Renderer::Property::DEPTH_INDEX);
- renderer.SetProperty( Dali::Renderer::Property::DEPTH_INDEX, depthIndex - 1 );
- mActor.Add( shadowActor );
- }
+ const bool drawShadow = STYLE_DROP_SHADOW == style;
+ CreateActors( meshContainerOutline,
+ textSize,
+ outlineColor,
+ shadowColor,
+ shadowOffset,
+ textControl,
+ animatablePropertyIndex,
+ drawShadow );
+
+ isShadowDrawn = drawShadow;
+ }
- if( hasRenderer )
- {
- mActor.Add( actor );
- }
- }
+ // For each MeshData object, create a mesh actor and add to the renderable actor
+ if( !meshContainer.empty() )
+ {
+ const bool drawShadow = !isShadowDrawn && ( STYLE_DROP_SHADOW == style );
+ CreateActors( meshContainer,
+ textSize,
+ defaultColor,
+ shadowColor,
+ shadowOffset,
+ textControl,
+ animatablePropertyIndex,
+ drawShadow );
}
+
#if defined(DEBUG_ENABLED)
Toolkit::AtlasGlyphManager::Metrics metrics = mGlyphManager.GetMetrics();
DALI_LOG_INFO( gLogFilter, Debug::General, "TextAtlasRenderer::GlyphManager::GlyphCount: %i, AtlasCount: %i, TextureMemoryUse: %iK\n",
{
for( Vector< TextCacheEntry >::Iterator oldTextIter = mTextCache.Begin(); oldTextIter != mTextCache.End(); ++oldTextIter )
{
- mGlyphManager.AdjustReferenceCount( oldTextIter->mFontId, oldTextIter->mIndex, -1/*decrement*/ );
+ mGlyphManager.AdjustReferenceCount( oldTextIter->mFontId, oldTextIter->mIndex, oldTextIter->mOutlineWidth, -1/*decrement*/ );
}
mTextCache.Resize( 0 );
}
actor.SetSize( actorSize );
actor.RegisterProperty("uOffset", Vector2::ZERO );
actor.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
+
return actor;
}
TextAbstraction::FontDescription defaultFontDescription;
TextAbstraction::PointSize26Dot6 defaultPointSize = TextAbstraction::FontClient::DEFAULT_POINT_SIZE;
- if( IsShowingPlaceholderText() && ( NULL != mEventData->mPlaceholderFont ) )
+ if( IsShowingPlaceholderText() && mEventData && ( NULL != mEventData->mPlaceholderFont ) )
{
// If the placeholder font is set specifically, only placeholder font is changed.
defaultFontDescription = mEventData->mPlaceholderFont->mFontDescription;
void Controller::Impl::OnCursorKeyEvent( const Event& event )
{
- if( NULL == mEventData )
+ if( NULL == mEventData || !IsShowingRealText() )
{
// Nothing to do if there is no text input.
return;
const SelectionBoxInfo& firstSelectionBoxLineInfo = *( selectionBoxLinesInfo.Begin() );
highLightPosition.y = firstSelectionBoxLineInfo.lineOffset;
- mEventData->mDecorator->SetHighLightBox( highLightPosition, highLightSize );
+ mEventData->mDecorator->SetHighLightBox( highLightPosition, highLightSize, static_cast<float>( mModel->GetOutlineWidth() ) );
if( !mEventData->mDecorator->IsSmoothHandlePanEnabled() )
{
Text::GetCursorPosition( parameters,
cursorInfo );
+ // Adds Outline offset.
+ const float outlineWidth = static_cast<float>( mModel->GetOutlineWidth() );
+ cursorInfo.primaryPosition.x += outlineWidth;
+ cursorInfo.primaryPosition.y += outlineWidth;
+ cursorInfo.secondaryPosition.x += outlineWidth;
+ cursorInfo.secondaryPosition.y += outlineWidth;
+
if( isMultiLine )
{
// If the text is editable and multi-line, the cursor position after a white space shouldn't exceed the boundaries of the text control.
return mImpl->mModel->mVisualModel->GetOutlineColor();
}
-void Controller::SetOutlineWidth( float width )
+void Controller::SetOutlineWidth( unsigned int width )
{
mImpl->mModel->mVisualModel->SetOutlineWidth( width );
mImpl->RequestRelayout();
}
-float Controller::GetOutlineWidth() const
+unsigned int Controller::GetOutlineWidth() const
{
return mImpl->mModel->mVisualModel->GetOutlineWidth();
}
Toolkit::DevelText::TextDirection::Type Controller::GetTextDirection()
{
- const LineRun* const firstline = mImpl->mModel->mVisualModel->mLines.Begin();
- if ( firstline && firstline->direction )
+ if( ( 0u == mImpl->mModel->mLogicalModel->mText.Count() ) )
+ {
+ return Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT;
+ }
+
+ const Character character = mImpl->mModel->mLogicalModel->mText[0];
+ Script script = TextAbstraction::GetCharacterScript( character );
+
+ if( TextAbstraction::IsRightToLeftScript( script ) )
{
return Toolkit::DevelText::TextDirection::RIGHT_TO_LEFT;
}
if( retrieveText )
{
- mImpl->GetText( numberOfWhiteSpaces, text );
+ if( !mImpl->IsShowingPlaceholderText() )
+ {
+ // Retrieves the normal text string.
+ mImpl->GetText( numberOfWhiteSpaces, text );
+ }
+ else
+ {
+ // When the current text is Placeholder Text, the surrounding text should be empty string.
+ // It means DALi should send empty string ("") to IME.
+ text = "";
+ }
}
ImfManager::ImfCallbackData callbackData( ( retrieveText || retrieveCursor ), cursorPosition, text, false );
const Vector<CharacterIndex>& glyphsToCharactersMap = mImpl->mModel->mVisualModel->mGlyphsToCharacters;
const Vector<Length>& charactersPerGlyph = mImpl->mModel->mVisualModel->mCharactersPerGlyph;
const Character* const textBuffer = mImpl->mModel->mLogicalModel->mText.Begin();
- float outlineWidth = mImpl->mModel->GetOutlineWidth();
+ const float outlineWidth = static_cast<float>( mImpl->mModel->GetOutlineWidth() );
// Set the layout parameters.
Layout::Parameters layoutParameters( size,
1,
UPDATE_INPUT_STYLE );
}
- else if( ( mImpl->mEventData->mPrimaryCursorPosition >= 0 ) && ( keyCode == Dali::DevelKey::DALI_KEY_DELETE ) )
+ else if( keyCode == Dali::DevelKey::DALI_KEY_DELETE )
{
// Remove the character after the current cursor position
removed = RemoveText( 0,
*
* @param[in] width The width in pixels of the outline, 0 indicates no outline
*/
- void SetOutlineWidth( float width );
+ void SetOutlineWidth( unsigned int width );
/**
* @brief Retrieves the width of an outline
*
* @return The width of the outline.
*/
- float GetOutlineWidth() const;
+ unsigned int GetOutlineWidth() const;
/**
* @brief Sets the emboss's properties string.
if( ENABLE_KEY == valueGet.first.stringKey )
{
/// Enable key.
- const std::string enableStr = valueGet.second.Get<std::string>();
- enabled = Text::TokenComparison( TRUE_TOKEN, enableStr.c_str(), enableStr.size() );
+ if( valueGet.second.GetType() == Dali::Property::STRING )
+ {
+ const std::string enableStr = valueGet.second.Get<std::string>();
+ enabled = Text::TokenComparison( TRUE_TOKEN, enableStr.c_str(), enableStr.size() );
+ }
+ else
+ {
+ enabled = valueGet.second.Get<bool>();
+ }
}
else if( COLOR_KEY == valueGet.first.stringKey )
{
/// Color key.
colorDefined = true;
- const std::string colorStr = valueGet.second.Get<std::string>();
-
- Text::ColorStringToVector4( colorStr.c_str(), colorStr.size(), color );
+ if( valueGet.second.GetType() == Dali::Property::STRING )
+ {
+ const std::string colorStr = valueGet.second.Get<std::string>();
+ Text::ColorStringToVector4( colorStr.c_str(), colorStr.size(), color );
+ }
+ else
+ {
+ color = valueGet.second.Get<Vector4>();
+ }
}
else if( HEIGHT_KEY == valueGet.first.stringKey )
{
/// Height key.
heightDefined = true;
- const std::string heightStr = valueGet.second.Get<std::string>();
-
- height = StringToFloat( heightStr.c_str() );
+ if( valueGet.second.GetType() == Dali::Property::STRING )
+ {
+ const std::string heightStr = valueGet.second.Get<std::string>();
+ height = StringToFloat( heightStr.c_str() );
+ }
+ else
+ {
+ height = valueGet.second.Get<float>();
+ }
}
}
bool& colorDefined,
Vector4& color,
bool& widthDefined,
- float& width )
+ unsigned int& width )
{
const unsigned int numberOfItems = underlinePropertiesMap.Count();
{
/// Width key.
widthDefined = true;
- width = valueGet.second.Get<float>();
+ width = static_cast<unsigned int>( valueGet.second.Get<float>() );
}
}
heightDefined,
height );
- controller->UnderlineSetByString( !empty);
+ controller->UnderlineSetByString( !empty );
}
}
else
bool colorDefined = false;
Vector4 color;
bool widthDefined = false;
- float width = 0.f;
+ unsigned int width = 0u;
bool empty = true;
update = true;
}
- if( widthDefined && ( fabsf( controller->GetOutlineWidth() - width ) > Math::MACHINE_EPSILON_1000 ) )
+ if( widthDefined && ( controller->GetOutlineWidth() != width ) )
{
controller->SetOutlineWidth( width );
update = true;
else
{
// Disable outline
- if( fabsf( controller->GetOutlineWidth() ) > Math::MACHINE_EPSILON_1000 )
+ if( 0u != controller->GetOutlineWidth() )
{
- controller->SetOutlineWidth( 0.0f );
+ controller->SetOutlineWidth( 0u );
update = true;
}
}
else
{
const Vector4& color = controller->GetOutlineColor();
- const float width = controller->GetOutlineWidth();
+ const unsigned int width = controller->GetOutlineWidth();
Property::Map map;
-
- std::string colorStr;
- Vector4ToColorString( color, colorStr );
- map.Insert( COLOR_KEY, colorStr );
-
- std::string widthStr;
- FloatToString( width, widthStr );
- map.Insert( WIDTH_KEY, widthStr );
+ map.Insert( COLOR_KEY, color );
+ map.Insert( WIDTH_KEY, static_cast<int>( width ) );
value = map;
bool& colorDefined,
Vector4& color,
bool& widthDefined,
- float& width );
+ unsigned int& width );
/**
* @brief Sets the underline properties.
virtual void GetUnderlineRuns( GlyphRun* underlineRuns,
UnderlineRunIndex index,
Length numberOfRuns ) const = 0;
+
+ /**
+ * @brief Retrieve the outline color.
+ *
+ * @return The outline color.
+ */
+ virtual const Vector4& GetOutlineColor() const = 0;
+
+ /**
+ * @brief Retrieves the width of an outline
+ *
+ * @return The width of the outline.
+ */
+ virtual unsigned int GetOutlineWidth() const = 0;
+
};
} // namespace Text
}
}
+const Vector4& View::GetOutlineColor() const
+{
+ if( mImpl->mVisualModel )
+ {
+ return mImpl->mVisualModel->GetOutlineColor();
+ }
+ return Vector4::ZERO;
+}
+
+unsigned int View::GetOutlineWidth() const
+{
+ if( mImpl->mVisualModel )
+ {
+ return mImpl->mVisualModel->GetOutlineWidth();
+ }
+ return 0u;
+}
+
} // namespace Text
} // namespace Toolkit
UnderlineRunIndex index,
Length numberOfRuns ) const;
+ /**
+ * @copydoc Dali::Toolkit::Text::ViewInterface::GetOutlineColor()
+ */
+ virtual const Vector4& GetOutlineColor() const;
+
+ /**
+ * @copydoc Dali::Toolkit::Text::ViewInterface::GetOutlineWidth()
+ */
+ virtual unsigned int GetOutlineWidth() const;
+
private:
// Undefined
mUnderlineHeight = height;
}
-void VisualModel::SetOutlineWidth( float width )
+void VisualModel::SetOutlineWidth( unsigned int width )
{
mOutlineWidth = width;
}
return mUnderlineHeight;
}
-float VisualModel::GetOutlineWidth() const
+unsigned int VisualModel::GetOutlineWidth() const
{
return mOutlineWidth;
}
mControlSize(),
mShadowOffset(),
mUnderlineHeight( 0.0f ),
- mOutlineWidth( 0.0f ),
+ mOutlineWidth( 0u ),
mShadowBlurRadius( 0.0f ),
mNaturalSize(),
mLayoutSize(),
*
* @param[in] width The width in pixels of the outline, 0 indicates no outline
*/
- void SetOutlineWidth( float width );
+ void SetOutlineWidth( unsigned int width );
/**
* @brief Retrieves the width of an outline
*
* @return The width of the outline.
*/
- float GetOutlineWidth() const;
+ unsigned int GetOutlineWidth() const;
protected:
Size mControlSize; ///< The size of the UI control.
Vector2 mShadowOffset; ///< Offset for drop shadow, 0 indicates no shadow
float mUnderlineHeight; ///< Fixed height for underline to override font metrics.
- float mOutlineWidth; ///< Width of outline.
+ unsigned int mOutlineWidth; ///< Width of outline.
float mShadowBlurRadius; ///< Blur radius of shadow, 0 indicates no blur.
private:
data->textureSet = mCache[ cachedIndex ]->textureSet;
NinePatchImage::StretchRanges stretchRangesX;
- stretchRangesX.PushBack( Uint16Pair( border.left, data->croppedWidth - border.right ) );
+ stretchRangesX.PushBack( Uint16Pair( border.left, ( (data->croppedWidth >= static_cast< unsigned int >( border.right )) ? data->croppedWidth - border.right : 0 ) ) );
NinePatchImage::StretchRanges stretchRangesY;
- stretchRangesY.PushBack( Uint16Pair( border.top, data->croppedHeight - border.bottom ) );
+ stretchRangesY.PushBack( Uint16Pair( border.top, ( (data->croppedHeight >= static_cast< unsigned int >( border.bottom )) ? data->croppedHeight - border.bottom : 0 ) ) );
data->stretchPixelsX = stretchRangesX;
data->stretchPixelsY = stretchRangesY;
data->textureSet.SetTexture( 0u, texture );
NinePatchImage::StretchRanges stretchRangesX;
- stretchRangesX.PushBack( Uint16Pair( border.left, data->croppedWidth - border.right ) );
+ stretchRangesX.PushBack( Uint16Pair( border.left, ( (data->croppedWidth >= static_cast< unsigned int >( border.right )) ? data->croppedWidth - border.right : 0 ) ) );
NinePatchImage::StretchRanges stretchRangesY;
- stretchRangesY.PushBack( Uint16Pair( border.top, data->croppedHeight - border.bottom ) );
+ stretchRangesY.PushBack( Uint16Pair( border.top, ( (data->croppedHeight >= static_cast< unsigned int >( border.bottom )) ? data->croppedHeight - border.bottom : 0 ) ) );
data->stretchPixelsX = stretchRangesX;
data->stretchPixelsY = stretchRangesY;
const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
attribute mediump vec2 aPosition;\n
varying mediump vec2 vTexCoord;\n
+ varying mediump vec2 vMaskTexCoord;\n
uniform mediump mat4 uMvpMatrix;\n
uniform mediump vec3 uSize;\n
uniform mediump vec2 uNinePatchFactorsX[ FACTOR_SIZE_X ];\n
mediump vec4 gridPosition = vec4( fixedFactor + ( visualSize.xy - fixedTotal ) * stretch / stretchTotal, 0.0, 1.0 );\n
mediump vec4 vertexPosition = gridPosition;\n
vertexPosition.xy -= visualSize.xy * vec2( 0.5, 0.5 );\n
- vertexPostion.xy += anchorPoint*visualSize + (visualOffset + origin)*uSize.xy;\n
+ vertexPosition.xy += anchorPoint*visualSize + (visualOffset + origin)*uSize.xy;\n
vertexPosition = uMvpMatrix * vertexPosition;\n
\n
vTexCoord = ( fixedFactor + stretch ) / ( fixedTotal + stretchTotal );\n
Uint16Pair stretchX = data->stretchPixelsX[ 0 ];
Uint16Pair stretchY = data->stretchPixelsY[ 0 ];
- uint16_t stretchWidth = stretchX.GetY() - stretchX.GetX();
- uint16_t stretchHeight = stretchY.GetY() - stretchY.GetX();
+ uint16_t stretchWidth = ( stretchX.GetY() >= stretchX.GetX() ) ? stretchX.GetY() - stretchX.GetX() : 0;
+ uint16_t stretchHeight = ( stretchY.GetY() >= stretchY.GetX() ) ? stretchY.GetY() - stretchY.GetX() : 0;
mImpl->mRenderer.RegisterProperty( "uFixed[0]", Vector2::ZERO );
mImpl->mRenderer.RegisterProperty( "uFixed[1]", Vector2( stretchX.GetX(), stretchY.GetX()) );
// INTERNAL HEADER
#include <dali-toolkit/public-api/visuals/text-visual-properties.h>
+#include <dali-toolkit/devel-api/visuals/text-visual-properties-devel.h>
#include <dali-toolkit/public-api/visuals/visual-properties.h>
#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
#include <dali-toolkit/internal/visuals/image-atlas-manager.h>
const char * const ENABLE_MARKUP_PROPERTY( "enableMarkup" );
const char * const SHADOW_PROPERTY( "shadow" );
const char * const UNDERLINE_PROPERTY( "underline" );
+const char * const OUTLINE_PROPERTY( "outline" );
const Vector4 FULL_TEXTURE_RECT( 0.f, 0.f, 1.f, 1.f );
{
result = Toolkit::TextVisual::Property::UNDERLINE;
}
+ else if( stringKey == OUTLINE_PROPERTY )
+ {
+ result = Toolkit::DevelTextVisual::Property::OUTLINE;
+ }
return result;
}
GetUnderlineProperties( mController, value, Text::EffectStyle::DEFAULT );
map.Insert( Toolkit::TextVisual::Property::UNDERLINE, value );
+
+ GetOutlineProperties( mController, value, Text::EffectStyle::DEFAULT );
+ map.Insert( Toolkit::DevelTextVisual::Property::OUTLINE, value );
}
void TextVisual::DoCreateInstancePropertyMap( Property::Map& map ) const
SetUnderlineProperties( mController, propertyValue, Text::EffectStyle::DEFAULT );
break;
}
+ case Toolkit::DevelTextVisual::Property::OUTLINE:
+ {
+ SetOutlineProperties( mController, propertyValue, Text::EffectStyle::DEFAULT );
+ break;
+ }
}
}
{
using Dali::EnvironmentVariable::GetEnvironmentVariable;
auto numberString = GetEnvironmentVariable(environmentVariable);
- auto numberOfThreads = numberString ? std::strtol(numberString, nullptr, 10) : 0;
- return (numberOfThreads > 0) ? numberOfThreads : defaultValue;
+ auto numberOfThreads = numberString ? std::strtoul(numberString, nullptr, 10) : 0;
+ constexpr auto MAX_NUMBER_OF_THREADS = 100u;
+ DALI_ASSERT_DEBUG( numberOfThreads < MAX_NUMBER_OF_THREADS );
+ return ( numberOfThreads > 0 && numberOfThreads < MAX_NUMBER_OF_THREADS ) ? numberOfThreads : defaultValue;
}
size_t GetNumberOfLocalLoaderThreads()
* ResouceReadySignal is done after the resource is set then signal will be missed.
*
* To protect against this, IsResourceReady() can be checked before connecting to ResourceReadySignal,
- * or the signal connection can be done before setting the resource"
+ * or the signal connection can be done before setting the resource.
*
* @code
* auto myImageView = ImageView::New( resourceUrl );
INPUT_LINE_SPACING,
/**
- * @brief The default underline parameters.
- * @details Name "underline", type Property::MAP.
- * @SINCE_1_2.13
+ * @copydoc Dali::Toolkit::TextLabel::Property::UNDERLINE
*/
UNDERLINE,
INPUT_UNDERLINE,
/**
- * @brief The default shadow parameters.
- * @details Name "shadow", type Property::MAP.
- * @SINCE_1_2.13
+ * @copydoc Dali::Toolkit::TextLabel::Property::SHADOW
*/
SHADOW,
INPUT_EMBOSS,
/**
- * @brief The default outline parameters.
- * @details Name "outline", type Property::MAP.
- * @SINCE_1_2.13
+ * @copydoc Dali::Toolkit::TextLabel::Property::OUTLINE
*/
OUTLINE,
INPUT_POINT_SIZE,
/**
- * @brief The default underline parameters.
- * @details Name "underline", type Property::MAP.
- * @SINCE_1_2.13
+ * @copydoc Dali::Toolkit::TextLabel::Property::UNDERLINE
*/
UNDERLINE,
INPUT_UNDERLINE,
/**
- * @brief The default shadow parameters.
- * @details Name "shadow", type Property::MAP.
- * @SINCE_1_2.13
+ * @copydoc Dali::Toolkit::TextLabel::Property::SHADOW
*/
SHADOW,
INPUT_EMBOSS,
/**
- * @brief The default outline parameters.
- * @details Name "outline", type Property::MAP.
- * @SINCE_1_2.13
+ * @copydoc Dali::Toolkit::TextLabel::Property::OUTLINE
*/
OUTLINE,
/**
* @brief The default underline parameters.
* @details Name "underline", type Property::MAP.
+ *
+ * The underline map contains the following keys:
+ *
+ * | %Property Name | Type | Required | Description |
+ * |----------------------|----------|----------|--------------------------------------------------------------------------------------------------------------------|
+ * | enable | BOOLEAN | No | True to enable the underline or false to disable (the default value is false) |
+ * | color | VECTOR4 | No | The color of the underline (the default value is Color::BLACK) |
+ * | height | FLOAT | No | The height of the underline (the default value is 0) |
+ *
* @SINCE_1_2.13
*/
UNDERLINE,
/**
* @brief The default shadow parameters.
* @details Name "shadow", type Property::MAP.
+ *
+ * The shadow map contains the following keys:
+ *
+ * | %Property Name | Type | Required | Description |
+ * |----------------------|----------|----------|--------------------------------------------------------------------------------------------------------------------|
+ * | color | VECTOR4 | No | The color of the shadow (the default value is Color::BLACK) |
+ * | offset | VECTOR2 | No | The offset from the text to draw the shadow in the X and Y axes (the default value is 0 which means no shadow) |
+ * | blurRadius | FLOAT | No | The radius of blur to be applied to the shadow (the default value is 0 which means no blur) |
+ *
* @SINCE_1_2.13
*/
SHADOW,
/**
* @brief The default outline parameters.
* @details Name "outline", type Property::MAP.
+ *
+ * The outline map contains the following keys:
+ *
+ * | %Property Name | Type | Required | Description |
+ * |----------------------|----------|----------|--------------------------------------------------------------------------------------------------------------------|
+ * | color | VECTOR4 | No | The color of the outline (the default value is Color::WHITE) |
+ * | width | INTEGER | No | The width of the outline (the default value is 0 which means no outline) |
+ *
* @SINCE_1_2.13
*/
OUTLINE,
const unsigned int TOOLKIT_MAJOR_VERSION = 1;
const unsigned int TOOLKIT_MINOR_VERSION = 3;
-const unsigned int TOOLKIT_MICRO_VERSION = 3;
+const unsigned int TOOLKIT_MICRO_VERSION = 4;
const char * const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
Name: dali-toolkit
Summary: Dali 3D engine Toolkit
-Version: 1.3.3
+Version: 1.3.4
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-3-Clause and MIT