Dali::Toolkit::DevelText::BitmapFontDescription description;
Dali::Toolkit::DevelText::Glyph glyph;
glyph.url = "BitmapFontUrl";
- glyph.utf8 = "BitmapFontUrl";
+ glyph.utf8[0u] = 0u;
+ glyph.utf8[1u] = 0u;
+ glyph.utf8[2u] = 0u;
+ glyph.utf8[3u] = 0u;
glyph.ascender = 1.f;
glyph.descender = 1.f;
description.glyphs.push_back( glyph );
#include <dali-toolkit-test-suite-utils.h>
#include <dali-toolkit/dali-toolkit.h>
#include <toolkit-text-utils.h>
+#include <dali-toolkit/internal/controls/text-controls/text-field-impl.h>
#include <dali-toolkit/internal/text/text-controller.h>
#include <dali-toolkit/internal/text/text-control-interface.h>
#include <dali-toolkit/internal/text/text-editable-control-interface.h>
END_TEST;
}
+
+int UtcDaliTextControllerSelectEvent(void)
+{
+ tet_infoline(" UtcDaliTextControllerSelectEvent");
+ ToolkitTestApplication application;
+
+ // Creates a text controller.
+ ControllerPtr controller = Controller::New();
+
+ // Configures the text controller similarly to the text-field.
+ ConfigureTextField( controller );
+
+ // Set the text
+ const std::string text("Hello World!");
+ controller->SetText( text );
+
+ // Select the whole text.
+ controller->SelectEvent( 0.f, 0.f, false );
+
+ // Perform a relayout
+ const Size size( Dali::Stage::GetCurrent().GetSize() );
+ controller->Relayout(size);
+
+ // Get the implementation of the text controller
+ Controller::Impl& mImpl = Controller::Impl::GetImplementation( *controller.Get() );
+
+ // Check if the whole text is selected or not.
+ std::string retrieved_text;
+ mImpl.RetrieveSelection( retrieved_text, false );
+ DALI_TEST_EQUALS( "Hello", retrieved_text, TEST_LOCATION );
+
+ // Select the whole text.
+ controller->SelectEvent( 0.f, 0.f, true );
+
+ // Perform a relayout
+ controller->Relayout( size );
+
+ mImpl.RetrieveSelection( retrieved_text, false );
+ DALI_TEST_EQUALS( text, retrieved_text, TEST_LOCATION );
+
+ END_TEST;
+}
#include <dali-toolkit/internal/text/rendering/view-model.h>
#include <dali-toolkit/internal/text/text-controller.h>
#include <dali-toolkit/devel-api/text/text-enumerations-devel.h>
+#include <dali/devel-api/text-abstraction/bitmap-font.h>
+#include <dali-toolkit/devel-api/text/bitmap-font.h>
using namespace Dali;
using namespace Toolkit;
tet_result(TET_PASS);
END_TEST;
}
+
+int UtcDaliTextTypesetterBitmapFont(void)
+{
+ tet_infoline("UtcDaliTextTypesetterBitmapFont ");
+ ToolkitTestApplication application;
+
+ DevelText::BitmapFontDescription fontDescription;
+ fontDescription.name = "Digits";
+ fontDescription.underlinePosition = 0.f;
+ fontDescription.underlineThickness = 0.f;
+ fontDescription.isColorFont = true;
+
+ fontDescription.glyphs.push_back( { TEST_RESOURCE_DIR "/fonts/bitmap/u0031.png", "0", 34.f, 0.f } );
+ fontDescription.glyphs.push_back( { TEST_RESOURCE_DIR "/fonts/bitmap/u0032.png", "1", 34.f, 0.f } );
+
+ TextAbstraction::BitmapFont bitmapFont;
+ DevelText::CreateBitmapFont( fontDescription, bitmapFont );
+
+ TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
+ fontClient.GetFontId( bitmapFont );
+
+ // Creates a text controller.
+ ControllerPtr controller = Controller::New();
+
+ // Configures the text controller similarly to the text-label.
+ ConfigureTextLabel( controller );
+
+ // Sets the text.
+ controller->SetMarkupProcessorEnabled( true );
+ controller->SetText( "<font family='Digits'><color 'value'='red'>0</color></font>" );
+
+ // Creates the text's model and relais-out the text.
+ const Size relayoutSize( 31.f, 34.f );
+ controller->Relayout( relayoutSize );
+
+ // Tests the rendering controller has been created.
+ TypesetterPtr renderingController = Typesetter::New( controller->GetTextModel() );
+ DALI_TEST_CHECK( renderingController );
+
+ controller->Relayout( relayoutSize );
+
+ // Renders the text and creates the final bitmap.
+ auto bitmap = renderingController->Render( relayoutSize, Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT );
+
+ DALI_TEST_EQUALS( 31u, bitmap.GetWidth(), TEST_LOCATION );
+ DALI_TEST_EQUALS( 34u, bitmap.GetHeight(), TEST_LOCATION );
+
+ tet_result(TET_PASS);
+ END_TEST;
+}
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 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.
{
}
+bool TestGlAbstraction::IsSurfacelessContextSupported() const
+{
+ return true;
+}
+
+bool TestGlAbstraction::TextureRequiresConverting( const GLenum imageGlFormat, const GLenum textureGlFormat, const bool isSubImage ) const
+{
+ return ( ( imageGlFormat == GL_RGB ) && ( textureGlFormat == GL_RGBA ) );
+}
+
} // Namespace dali
bool BlendEnabled(const Dali::TraceCallStack& callStack)
#define TEST_GL_ABSTRACTION_H
/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 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.
void PreRender();
void PostRender();
+ bool IsSurfacelessContextSupported() const;
+
+ bool TextureRequiresConverting( const GLenum imageGlFormat, const GLenum textureGlFormat, const bool isSubImage ) const;
+
/* OpenGL ES 2.0 */
inline void ActiveTexture( GLenum textureUnit )
void SetRenderer( Dali::Renderer renderer )
{
mRenderer = renderer;
+
+ if( mWidth != 0 && mHeight != 0 )
+ {
+ Dali::TextureSet textureSet = mRenderer.GetTextures();
+ Dali::Texture texture = Dali::Texture::New( TextureType::TEXTURE_2D, Pixel::RGBA8888, mWidth, mHeight );
+ textureSet.SetTexture( 0, texture );
+ }
}
void SetSize( uint32_t width, uint32_t height )
{
mWidth = width;
mHeight = height;
- }
- bool StartRender()
- {
- return true;
+ if( mRenderer )
+ {
+ Dali::TextureSet textureSet = mRenderer.GetTextures();
+ Dali::Texture texture = Dali::Texture::New( TextureType::TEXTURE_2D, Pixel::RGBA8888, mWidth, mHeight );
+ textureSet.SetTexture( 0, texture );
+ }
}
void StopRender()
return 60.0f;
}
+ void GetDefaultSize( uint32_t& width, uint32_t& height ) const
+ {
+ width = 100;
+ height = 100;
+ }
+
public:
std::string mUrl;
Dali::Renderer mRenderer;
uint32_t mWidth;
uint32_t mHeight;
-
};
inline VectorAnimationRenderer& GetImplementation( Dali::VectorAnimationRenderer& renderer )
Internal::Adaptor::GetImplementation( *this ).SetSize( width, height );
}
-bool VectorAnimationRenderer::StartRender()
-{
- return Internal::Adaptor::GetImplementation( *this ).StartRender();
-}
-
void VectorAnimationRenderer::StopRender()
{
Internal::Adaptor::GetImplementation( *this ).StopRender();
return Internal::Adaptor::GetImplementation( *this ).GetFrameRate();
}
+void VectorAnimationRenderer::GetDefaultSize( uint32_t& width, uint32_t& height ) const
+{
+ Internal::Adaptor::GetImplementation( *this ).GetDefaultSize( width, height );
+}
+
} // namespace Dali;
Vector2 controlSize( 20.f, 30.f );
Vector2 naturalSize;
- actor.SetSize( controlSize );
Stage::GetCurrent().Add( actor );
application.SendNotification();
visual.GetNaturalSize( naturalSize );
+ DALI_TEST_EQUALS( naturalSize, Vector2( 100.0f, 100.0f ), TEST_LOCATION ); // 100x100 is the content default size.
+
+ actor.SetSize( controlSize );
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+ visual.GetNaturalSize( naturalSize );
+
DALI_TEST_EQUALS( naturalSize, controlSize, TEST_LOCATION );
END_TEST;
const char* const PROPERTY_NAME_ENABLE_SHIFT_SELECTION = "enableShiftSelection";
const char* const PROPERTY_NAME_ENABLE_GRAB_HANDLE = "enableGrabHandle";
const char* const PROPERTY_NAME_MATCH_SYSTEM_LANGUAGE_DIRECTION = "matchSystemLanguageDirection";
+const char* const PROPERTY_NAME_ENABLE_GRAB_HANDLE_POPUP = "enableGrabHandlePopup";
const Vector4 PLACEHOLDER_TEXT_COLOR( 0.8f, 0.8f, 0.8f, 0.8f );
const Dali::Vector4 LIGHT_BLUE( 0.75f, 0.96f, 1.f, 1.f ); // The text highlight color.
DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_ENABLE_SHIFT_SELECTION ) == DevelTextField::Property::ENABLE_SHIFT_SELECTION );
DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_ENABLE_GRAB_HANDLE ) == DevelTextField::Property::ENABLE_GRAB_HANDLE );
DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_MATCH_SYSTEM_LANGUAGE_DIRECTION ) == DevelTextField::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION );
+ DALI_TEST_CHECK( field.GetPropertyIndex( PROPERTY_NAME_ENABLE_GRAB_HANDLE_POPUP ) == DevelTextField::Property::ENABLE_GRAB_HANDLE_POPUP );
END_TEST;
}
field.SetProperty( Actor::Property::LAYOUT_DIRECTION, LayoutDirection::RIGHT_TO_LEFT );
DALI_TEST_EQUALS( field.GetProperty<int>( Actor::Property::LAYOUT_DIRECTION ), static_cast<int>( LayoutDirection::RIGHT_TO_LEFT ), TEST_LOCATION );
+ // Test the ENABLE_GRAB_HANDLE_POPUP property
+ DALI_TEST_CHECK( field.GetProperty<bool>( DevelTextField::Property::ENABLE_GRAB_HANDLE_POPUP ) );
+ field.SetProperty( DevelTextField::Property::ENABLE_GRAB_HANDLE_POPUP, false );
+ DALI_TEST_CHECK( !field.GetProperty<bool>( DevelTextField::Property::ENABLE_GRAB_HANDLE_POPUP ) );
+
application.SendNotification();
application.Render();
END_TEST;
}
-
int UtcDaliTextFieldGetInputMethodContext(void)
{
ToolkitTestApplication application;
END_TEST;
}
+int UtcDaliTextFieldSelectWholeText(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliTextFieldSelectWholeText ");
+
+ TextField textField = TextField::New();
+
+ Stage::GetCurrent().Add( textField );
+
+ textField.SetSize( 300.f, 50.f );
+ textField.SetParentOrigin( ParentOrigin::TOP_LEFT );
+ textField.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+
+ // Avoid a crash when core load gl resources.
+ application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( 1u, textField.GetChildCount(), TEST_LOCATION );
+
+ DevelTextField::SelectWholeText( textField );
+
+ application.SendNotification();
+ application.Render();
+
+ // Nothing should have been selected. The number of children is still 1
+ DALI_TEST_EQUALS( 1u, textField.GetChildCount(), TEST_LOCATION );
+
+ textField.SetProperty( TextField::Property::TEXT, "Hello world" );
+
+ application.SendNotification();
+ application.Render();
+
+ DevelTextField::SelectWholeText( textField );
+
+ application.SendNotification();
+ application.Render();
+
+ // Should be 2 children, the stencil and the layer
+ DALI_TEST_EQUALS( 2u, textField.GetChildCount(), TEST_LOCATION );
+
+ // The offscreen root actor should have two actors: the renderer and the highlight actor.
+ Actor stencil = textField.GetChildAt( 0u );
+
+ // The highlight actor is drawn first, so is the first actor in the list
+ Renderer highlight = stencil.GetChildAt( 0u ).GetRendererAt( 0u );
+ DALI_TEST_CHECK( highlight );
+
+ END_TEST;
+}
#include <dali-toolkit/devel-api/controls/text-controls/text-label-devel.h>
#include <dali-toolkit/devel-api/controls/text-controls/text-style-properties-devel.h>
#include <dali-toolkit/devel-api/text/text-enumerations-devel.h>
+#include <dali/devel-api/text-abstraction/bitmap-font.h>
+#include <dali-toolkit/devel-api/text/bitmap-font.h>
using namespace Dali;
using namespace Toolkit;
label.SetProperty( TextLabel::Property::TEXT, "<color value='white'>Markup</color><color value='cyan'>Text</color>" );
DALI_TEST_EQUALS( label.GetProperty<std::string>( TextLabel::Property::TEXT ), std::string("MarkupText"), TEST_LOCATION );
- application.SendNotification();
- application.Render();
+ // Check for incomplete marks.
+ label.SetProperty( TextLabel::Property::TEXT, "<color='white'><i>Markup</i><b>Text</b></color>" );
+ DALI_TEST_EQUALS( label.GetProperty<std::string>( TextLabel::Property::TEXT ), std::string("MarkupText"), TEST_LOCATION );
+ try
+ {
+ application.SendNotification();
+ application.Render();
+ }
+ catch( ... )
+ {
+ tet_result(TET_FAIL);
+ }
// Check autoscroll properties
const int SCROLL_SPEED = 80;
END_TEST;
}
+
+int UtcDaliToolkitTextLabelBitmapFont(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliToolkitTextLabelBitmapFont");
+
+ DevelText::BitmapFontDescription fontDescription;
+ fontDescription.name = "Digits";
+ fontDescription.underlinePosition = 0.f;
+ fontDescription.underlineThickness = 0.f;
+
+ fontDescription.glyphs.push_back( { TEST_RESOURCE_DIR "/fonts/bitmap/u0030.png", ":", 34.f, 0.f } );
+ fontDescription.glyphs.push_back( { TEST_RESOURCE_DIR "/fonts/bitmap/u0031.png", "0", 34.f, 0.f } );
+ fontDescription.glyphs.push_back( { TEST_RESOURCE_DIR "/fonts/bitmap/u0032.png", "1", 34.f, 0.f } );
+ fontDescription.glyphs.push_back( { TEST_RESOURCE_DIR "/fonts/bitmap/u0033.png", "2", 34.f, 0.f } );
+ fontDescription.glyphs.push_back( { TEST_RESOURCE_DIR "/fonts/bitmap/u0034.png", "3", 34.f, 0.f } );
+ fontDescription.glyphs.push_back( { TEST_RESOURCE_DIR "/fonts/bitmap/u0035.png", "4", 34.f, 0.f } );
+ fontDescription.glyphs.push_back( { TEST_RESOURCE_DIR "/fonts/bitmap/u0036.png", "5", 34.f, 0.f } );
+ fontDescription.glyphs.push_back( { TEST_RESOURCE_DIR "/fonts/bitmap/u0037.png", "6", 34.f, 0.f } );
+ fontDescription.glyphs.push_back( { TEST_RESOURCE_DIR "/fonts/bitmap/u0038.png", "7", 34.f, 0.f } );
+ fontDescription.glyphs.push_back( { TEST_RESOURCE_DIR "/fonts/bitmap/u0039.png", "8", 34.f, 0.f } );
+ fontDescription.glyphs.push_back( { TEST_RESOURCE_DIR "/fonts/bitmap/u003a.png", "9", 34.f, 0.f } );
+
+ TextAbstraction::BitmapFont bitmapFont;
+ DevelText::CreateBitmapFont( fontDescription, bitmapFont );
+
+ TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
+ fontClient.GetFontId( bitmapFont );
+
+ TextLabel label = TextLabel::New();
+
+ label.SetProperty( TextLabel::Property::TEXT, "0123456789:" );
+ label.SetProperty( TextLabel::Property::FONT_FAMILY, "Digits" );
+
+ // The text has been laid out with the bitmap font if the natural size is the sum of all the width (322) and 34 height.
+ DALI_TEST_EQUALS( label.GetNaturalSize(), Vector3(322.f, 34.f, 0.f), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+
+ Stage::GetCurrent().Add( label );
+
+ application.SendNotification();
+ application.Render();
+
+ // The text has been rendered if the height of the text-label is the height of the line.
+ DALI_TEST_EQUALS( label.GetCurrentSize().height, 34.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+
+ END_TEST;
+}
return GetImpl( textField ).GetInputMethodContext();
}
+void SelectWholeText( TextField textField )
+{
+ GetImpl( textField ).SelectWholeText();
+}
+
} // namespace DevelText
} // namespace Toolkit
* @details Name "matchSystemLanguageDirection", type (Property::BOOLEAN), Read/Write
* @note The default value is false
*/
- MATCH_SYSTEM_LANGUAGE_DIRECTION = ELLIPSIS + 3
+ MATCH_SYSTEM_LANGUAGE_DIRECTION = ELLIPSIS + 3,
+
+ /**
+ * @brief Enables the grab handle popup for text selection.
+ * @details Name "enableGrabHandlePopup", type Property::BOOLEAN.
+ * @note The default value is true, which means the grab handle popup is enabled by default.
+ */
+ ENABLE_GRAB_HANDLE_POPUP = ELLIPSIS + 4
};
} // namespace Property
*/
DALI_TOOLKIT_API InputMethodContext GetInputMethodContext( TextField textField );
+/**
+ * @brief Select the whole text of TextField.
+ *
+ * @param[in] textField The instance of TextField.
+ * @return InputMethodContext instance.
+ */
+DALI_TOOLKIT_API void SelectWholeText( TextField textField );
+
} // namespace DevelText
} // namespace Toolkit
#include <dali-toolkit/devel-api/text/bitmap-font.h>
// EXTERNAL INCLUDE
-#include <dali/public-api/common/dali-vector.h>
#include <dali/devel-api/text-abstraction/bitmap-font.h>
+#include <cstring>
// INTERNAL INCLUDE
#include <dali-toolkit/internal/text/character-set-conversion.h>
-#include <dali-toolkit/internal/text/text-definitions.h>
-
namespace Dali
{
namespace Toolkit
{
-using namespace Text;
+
namespace DevelText
{
Glyph::Glyph()
: url{},
- utf8{ 0u },
+ utf8{},
ascender{ 0.f },
descender{ 0.f }
{}
+Glyph::Glyph( const std::string& url, const std::string utf8Character, float ascender, float descender )
+: url{ url },
+ utf8{},
+ ascender{ ascender },
+ descender{ descender }
+{
+ DALI_ASSERT_DEBUG( utf8Character.size() <= 4u );
+
+ std::copy( utf8Character.begin(), utf8Character.end(), utf8 );
+}
+
Glyph::~Glyph()
{}
: glyphs{},
name{},
underlinePosition{ 0.f },
- underlineThickness{ 1.f }
+ underlineThickness{ 1.f },
+ isColorFont{ false }
{}
BitmapFontDescription::~BitmapFontDescription()
bitmapFont.name = description.name;
bitmapFont.underlinePosition = description.underlinePosition;
bitmapFont.underlineThickness = description.underlineThickness;
+ bitmapFont.isColorFont = description.isColorFont;
for( const auto& glyph : description.glyphs )
{
- // 1) Convert to utf32
- Vector<Character> utf32;
- utf32.Resize( glyph.utf8.size() );
-
- const uint32_t numberOfCharacters = ( glyph.utf8.size() == 0 ) ? 0 :
- Text::Utf8ToUtf32( reinterpret_cast<const uint8_t* const>( glyph.utf8.c_str() ),
- glyph.utf8.size(),
- &utf32[0u] );
- utf32.Resize( numberOfCharacters );
+ uint32_t c = 0u;
+ Text::Utf8ToUtf32( glyph.utf8, Text::GetUtf8Length( glyph.utf8[0u] ), &c );
- TextAbstraction::BitmapGlyph bitmapGlyph( glyph.url, utf32[0u], glyph.ascender, glyph.descender );
+ TextAbstraction::BitmapGlyph bitmapGlyph( glyph.url, c, glyph.ascender, glyph.descender );
bitmapFont.glyphs.push_back( std::move( bitmapGlyph ) );
}
Glyph();
/**
+ * @brief Constructor.
+ *
+ * Initialize the members with the given values.
+ *
+ * @param[in] url The url of the bitmap for that glyph.
+ * @param[in] utf8 The utf8 codification of the glyph.
+ * @param[in] ascender The ascender of the glyph.
+ * @param[in] descender The descender of the glyph.
+ */
+ Glyph( const std::string& url, const std::string utf8, float ascender, float descender );
+
+ /**
* @brief Default destructor.
*/
~Glyph();
- std::string url; ///< The url of the glyph.
- std::string utf8; ///< the glyph encoded in utf8
- float ascender; ///< The ascender. The distance from the base line to the top of the glyph.
- float descender; ///< The descender. The distance from the base line to the bottom of the glyph.
+ std::string url; ///< The url of the glyph.
+ uint8_t utf8[4]; ///< the glyph encoded in utf8
+ float ascender; ///< The ascender. The distance from the base line to the top of the glyph.
+ float descender; ///< The descender. The distance from the base line to the bottom of the glyph.
};
/**
std::string name; ///< Name of the font.
float underlinePosition; ///< The position of the underline from the base line.
float underlineThickness; ///< The thickness of the underline.
+ bool isColorFont:1; ///< Whether the glyphs of this font have their own colors.
};
/**
// Set the position of the embedded items (if there is any).
EmbeddedItemInfo* embeddedItemLayoutBuffer = embeddedItemLayout.Begin();
- auto transformToArc = isClockwise ? &Dali::TextAbstraction::TransformToArcClockwise : &Dali::TextAbstraction::TransformToArcAntiClockwise;
-
for( Length index = 0u, endIndex = embeddedItemLayout.Count(); index < endIndex; ++index )
{
EmbeddedItemInfo& embeddedItem = *( embeddedItemLayoutBuffer + index );
}
embeddedItem.angle = Degree( Radian( radians ) );
- transformToArc( circularTextParameters, centerX, centerY );
+ Dali::TextAbstraction::TransformToArc( circularTextParameters, centerX, centerY );
// Recalculate the size of the embedded item after the rotation to position it correctly.
float width = embeddedItem.size.width;
DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "enableShiftSelection", BOOLEAN, ENABLE_SHIFT_SELECTION )
DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "enableGrabHandle", BOOLEAN, ENABLE_GRAB_HANDLE )
DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "matchSystemLanguageDirection", BOOLEAN, MATCH_SYSTEM_LANGUAGE_DIRECTION )
+DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "enableGrabHandlePopup", BOOLEAN, ENABLE_GRAB_HANDLE_POPUP )
DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "textChanged", SIGNAL_TEXT_CHANGED )
DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "maxLengthReached", SIGNAL_MAX_LENGTH_REACHED )
}
break;
}
+ case Toolkit::DevelTextField::Property::ENABLE_GRAB_HANDLE_POPUP:
+ {
+ if (impl.mController)
+ {
+ const bool grabHandlePopupEnabled = value.Get<bool>();
+ DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p ENABLE_GRAB_HANDLE_POPUP %d\n", impl.mController.Get(), grabHandlePopupEnabled);
+
+ impl.mController->SetGrabHandlePopupEnabled(grabHandlePopupEnabled);
+ break;
+ }
+ }
} // switch
} // textfield
}
}
break;
}
+ case Toolkit::DevelTextField::Property::ENABLE_GRAB_HANDLE_POPUP:
+ {
+ if (impl.mController)
+ {
+ value = impl.mController->IsGrabHandlePopupEnabled();
+ }
+ break;
+ }
} //switch
}
return value;
}
+void TextField::SelectWholeText()
+{
+ if( mController && mController->IsShowingRealText() )
+ {
+ mController->SelectEvent( 0.f, 0.f, true );
+ SetKeyInputFocus();
+ }
+}
+
InputMethodContext TextField::GetInputMethodContext()
{
return mInputMethodContext;
*/
Toolkit::TextField::InputStyleChangedSignalType& InputStyleChangedSignal();
+ /**
+ * @brief Called to select the whole texts.
+ */
+ void SelectWholeText();
+
private: // From Control
/**
StyleStack::RunIndex colorRunIndex = 0u;
StyleStack::RunIndex fontRunIndex = 0u;
+ // check tag reference
+ int colorTagReference = 0u;
+ int fontTagReference = 0u;
+ int iTagReference = 0u;
+ int bTagReference = 0u;
+
// Give an initial default value to the model's vectors.
markupProcessData.colorRuns.Reserve( DEFAULT_VECTOR_SIZE );
markupProcessData.fontRuns.Reserve( DEFAULT_VECTOR_SIZE );
// Point the next color run.
++colorRunIndex;
+
+ // Increase reference
+ ++colorTagReference;
}
else
{
- // Pop the top of the stack and set the number of characters of the run.
- ColorRun& colorRun = *( markupProcessData.colorRuns.Begin() + styleStack.Pop() );
- colorRun.characterRun.numberOfCharacters = characterIndex - colorRun.characterRun.characterIndex;
+ if( colorTagReference > 0 )
+ {
+ // Pop the top of the stack and set the number of characters of the run.
+ ColorRun& colorRun = *( markupProcessData.colorRuns.Begin() + styleStack.Pop() );
+ colorRun.characterRun.numberOfCharacters = characterIndex - colorRun.characterRun.characterIndex;
+ --colorTagReference;
+ }
}
} // <color></color>
else if( TokenComparison( XHTML_I_TAG, tag.buffer, tag.length ) )
// Point the next free font run.
++fontRunIndex;
+
+ // Increase reference
+ ++iTagReference;
}
else
{
- // Pop the top of the stack and set the number of characters of the run.
- FontDescriptionRun& fontRun = *( markupProcessData.fontRuns.Begin() + styleStack.Pop() );
- fontRun.characterRun.numberOfCharacters = characterIndex - fontRun.characterRun.characterIndex;
+ if( iTagReference > 0 )
+ {
+ // Pop the top of the stack and set the number of characters of the run.
+ FontDescriptionRun& fontRun = *( markupProcessData.fontRuns.Begin() + styleStack.Pop() );
+ fontRun.characterRun.numberOfCharacters = characterIndex - fontRun.characterRun.characterIndex;
+ --iTagReference;
+ }
}
} // <i></i>
else if( TokenComparison( XHTML_U_TAG, tag.buffer, tag.length ) )
// Point the next free font run.
++fontRunIndex;
+
+ // Increase reference
+ ++bTagReference;
}
else
{
- // Pop the top of the stack and set the number of characters of the run.
- FontDescriptionRun& fontRun = *( markupProcessData.fontRuns.Begin() + styleStack.Pop() );
- fontRun.characterRun.numberOfCharacters = characterIndex - fontRun.characterRun.characterIndex;
+ if( bTagReference > 0 )
+ {
+ // Pop the top of the stack and set the number of characters of the run.
+ FontDescriptionRun& fontRun = *( markupProcessData.fontRuns.Begin() + styleStack.Pop() );
+ fontRun.characterRun.numberOfCharacters = characterIndex - fontRun.characterRun.characterIndex;
+ --bTagReference;
+ }
}
} // <b></b>
else if( TokenComparison( XHTML_FONT_TAG, tag.buffer, tag.length ) )
// Point the next free font run.
++fontRunIndex;
+
+ // Increase reference
+ ++fontTagReference;
}
else
{
- // Pop the top of the stack and set the number of characters of the run.
- FontDescriptionRun& fontRun = *( markupProcessData.fontRuns.Begin() + styleStack.Pop() );
- fontRun.characterRun.numberOfCharacters = characterIndex - fontRun.characterRun.characterIndex;
+ if( fontTagReference > 0 )
+ {
+ // Pop the top of the stack and set the number of characters of the run.
+ FontDescriptionRun& fontRun = *( markupProcessData.fontRuns.Begin() + styleStack.Pop() );
+ fontRun.characterRun.numberOfCharacters = characterIndex - fontRun.characterRun.characterIndex;
+ --fontTagReference;
+ }
}
} // <font></font>
else if( TokenComparison( XHTML_SHADOW_TAG, tag.buffer, tag.length ) )
if ( Pixel::RGBA8888 == pixelFormat )
{
// Whether the given glyph is a color one.
- const bool isColorGlyph = Pixel::BGRA8888 == data.glyphBitmap.format;
+ const bool isColorGlyph = data.glyphBitmap.isColorEmoji || data.glyphBitmap.isColorBitmap;
+ const uint32_t glyphPixelSize = Pixel::GetBytesPerPixel( data.glyphBitmap.format );
+ const uint32_t alphaIndex = glyphPixelSize - 1u;
+ const bool swapChannelsBR = Pixel::BGRA8888 == data.glyphBitmap.format;
// Pointer to the color glyph if there is one.
const uint32_t* const colorGlyphBuffer = isColorGlyph ? reinterpret_cast<uint32_t*>( data.glyphBitmap.buffer ) : NULL;
// Initial vertical offset.
const int yOffset = data.verticalOffset + position->y;
+ uint32_t* bitmapBuffer = reinterpret_cast< uint32_t* >( data.bitmapBuffer.GetBuffer() );
+
// Traverse the pixels of the glyph line per line.
for( int lineIndex = 0, glyphHeight = static_cast<int>( data.glyphBitmap.height ); lineIndex < glyphHeight; ++lineIndex )
{
continue;
}
- uint32_t* bitmapBuffer = reinterpret_cast< uint32_t* >( data.bitmapBuffer.GetBuffer() );
-
if( isColorGlyph )
{
- // Retrieves the color from the color glyph. The format is BGRA8888.
+ // Retrieves the color from the color glyph.
uint32_t packedColorGlyph = *( colorGlyphBuffer + glyphBufferOffset + index );
uint8_t* packedColorGlyphBuffer = reinterpret_cast<uint8_t*>( &packedColorGlyph );
}
else
{
- uint8_t colorAlpha = static_cast<uint8_t>( color->a * static_cast<float>( *( packedColorGlyphBuffer + 3u ) ) );
+ const uint8_t colorAlpha = static_cast<uint8_t>( color->a * static_cast<float>( *( packedColorGlyphBuffer + 3u ) ) );
*( packedColorGlyphBuffer + 3u ) = colorAlpha;
if( Typesetter::STYLE_SHADOW == style )
}
else
{
- std::swap( *packedColorGlyphBuffer, *( packedColorGlyphBuffer + 2u ) ); // Swap B and R.
+ if( swapChannelsBR )
+ {
+ std::swap( *packedColorGlyphBuffer, *( packedColorGlyphBuffer + 2u ) ); // Swap B and R.
+ }
*( packedColorGlyphBuffer + 2u ) = ( *( packedColorGlyphBuffer + 2u ) * colorAlpha / 255 );
*( packedColorGlyphBuffer + 1u ) = ( *( packedColorGlyphBuffer + 1u ) * colorAlpha / 255 );
*packedColorGlyphBuffer = ( *( packedColorGlyphBuffer ) * colorAlpha / 255 );
+
+ if( data.glyphBitmap.isColorBitmap )
+ {
+ *( packedColorGlyphBuffer + 2u ) = static_cast<uint8_t>( *( packedColorGlyphBuffer + 2u ) * color->b );
+ *( packedColorGlyphBuffer + 1u ) = static_cast<uint8_t>( *( packedColorGlyphBuffer + 1u ) * color->g );
+ *packedColorGlyphBuffer = static_cast<uint8_t>( *packedColorGlyphBuffer * color->r );
+ }
}
}
uint8_t* packedColorBuffer = reinterpret_cast<uint8_t*>( &packedColor );
// Update the alpha channel.
- const uint8_t alpha = *( data.glyphBitmap.buffer + glyphBufferOffset + index );
+ const uint8_t alpha = *( data.glyphBitmap.buffer + glyphPixelSize * ( glyphBufferOffset + index ) + alphaIndex );
// Copy non-transparent pixels only
if ( alpha > 0u )
else
{
// Whether the given glyph is a color one.
- const bool isColorGlyph = Pixel::BGRA8888 == data.glyphBitmap.format;
+ const bool isColorGlyph = data.glyphBitmap.isColorEmoji || data.glyphBitmap.isColorBitmap;
+ const uint32_t glyphPixelSize = Pixel::GetBytesPerPixel( data.glyphBitmap.format );
+ const uint32_t alphaIndex = glyphPixelSize - 1u;
// Initial vertical offset.
const int yOffset = data.verticalOffset + position->y;
+ uint8_t* bitmapBuffer = reinterpret_cast< uint8_t* >( data.bitmapBuffer.GetBuffer() );
+
// Traverse the pixels of the glyph line per line.
for( int lineIndex = 0, glyphHeight = static_cast<int>( data.glyphBitmap.height ); lineIndex < glyphHeight; ++lineIndex )
{
continue;
}
- uint8_t* bitmapBuffer = reinterpret_cast< uint8_t* >( data.bitmapBuffer.GetBuffer() );
-
if ( !isColorGlyph )
{
// Update the alpha channel.
- const uint8_t alpha = *( data.glyphBitmap.buffer + glyphBufferOffset + index );
+ const uint8_t alpha = *( data.glyphBitmap.buffer + glyphPixelSize * ( glyphBufferOffset + index ) + alphaIndex );
// Copy non-transparent pixels only
if ( alpha > 0u )
// overwrite a previous bigger alpha with a smaller alpha (in order to avoid
// semi-transparent gaps between joint glyphs with overlapped pixels, which could
// happen, for example, in the RTL text when we copy glyphs from right to left).
- *( bitmapBuffer + verticalOffset + xOffsetIndex ) = std::max( currentAlpha, alpha );
+ currentAlpha = std::max( currentAlpha, alpha );
}
}
}
if( mEventData->mSelectionEnabled )
{
- ChangeState( EventData::SELECTING );
+ // Calculates the logical position from the start.
+ RepositionSelectionHandles( 0.f - mModel->mScrollPosition.x,
+ 0.f - mModel->mScrollPosition.y,
+ Controller::NoTextTap::HIGHLIGHT );
mEventData->mLeftSelectionPosition = 0u;
mEventData->mRightSelectionPosition = mModel->mLogicalModel->mText.Count();
-
- mEventData->mScrollAfterUpdatePosition = true;
- mEventData->mUpdateLeftSelectionPosition = true;
- mEventData->mUpdateRightSelectionPosition = true;
- mEventData->mUpdateHighlightBox = true;
}
}
mImpl->mLayoutDirection = layoutDirection;
}
+bool Controller::IsShowingRealText() const
+{
+ return mImpl->IsShowingRealText();
+}
+
void Controller::SetLineWrapMode( Text::LineWrap::Mode lineWrapMode )
{
return mImpl->mEventData->mGrabHandleEnabled;
}
+void Controller::SetGrabHandlePopupEnabled(bool enabled)
+{
+ mImpl->mEventData->mGrabHandlePopupEnabled = enabled;
+}
+
+bool Controller::IsGrabHandlePopupEnabled() const
+{
+ return mImpl->mEventData->mGrabHandlePopupEnabled;
+}
+
// public : Update
void Controller::SetText( const std::string& text )
}
}
+void Controller::SelectEvent( float x, float y, bool selectAll )
+{
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::SelectEvent\n" );
+
+ if( NULL != mImpl->mEventData )
+ {
+ if( selectAll )
+ {
+ Event event( Event::SELECT_ALL );
+ mImpl->mEventData->mEventQueue.push_back( event );
+ }
+ else
+ {
+ Event event( Event::SELECT );
+ event.p2.mFloat = x;
+ event.p3.mFloat = y;
+ mImpl->mEventData->mEventQueue.push_back( event );
+ }
+
+ mImpl->mEventData->mCheckScrollAmount = true;
+ mImpl->mEventData->mIsLeftHandleSelected = true;
+ mImpl->mEventData->mIsRightHandleSelected = true;
+ mImpl->RequestRelayout();
+ }
+}
+
InputMethodContext::CallbackData Controller::OnInputMethodContextEvent( InputMethodContext& inputMethodContext, const InputMethodContext::EventData& inputMethodContextEvent )
{
// Whether the text needs to be relaid-out.
mImpl->mOperationsPending = ALL_OPERATIONS;
}
-void Controller::SelectEvent( float x, float y, bool selectAll )
-{
- DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::SelectEvent\n" );
-
- if( NULL != mImpl->mEventData )
- {
- if( selectAll )
- {
- Event event( Event::SELECT_ALL );
- mImpl->mEventData->mEventQueue.push_back( event );
- }
- else
- {
- Event event( Event::SELECT );
- event.p2.mFloat = x;
- event.p3.mFloat = y;
- mImpl->mEventData->mEventQueue.push_back( event );
- }
-
- mImpl->mEventData->mCheckScrollAmount = true;
- mImpl->mEventData->mIsLeftHandleSelected = true;
- mImpl->mEventData->mIsRightHandleSelected = true;
- mImpl->RequestRelayout();
- }
-}
-
bool Controller::DeleteEvent( int keyCode )
{
DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::KeyEvent %p KeyCode : %d \n", this, keyCode );
bool IsGrabHandleEnabled() const;
/**
+ * @brief Enable or disable the grab handles for text selection.
+ *
+ * @param[in] enabled Whether to enable the grab handles
+ */
+ void SetGrabHandlePopupEnabled( bool enabled );
+
+ /**
+ * @brief Returns whether the grab handles are enabled.
+ *
+ * @return True if the grab handles are enabled
+ */
+ bool IsGrabHandlePopupEnabled() const;
+
+ /**
* @brief Sets input type to password
*
* @note The string is displayed hidden character
*/
void SetLayoutDirection( Dali::LayoutDirection::Type layoutDirection );
+ /**
+ * @brief Retrieves if showing real text or not.
+ * @return The value of showing real text.
+ */
+ bool IsShowingRealText() const;
public: // Relayout.
void LongPressEvent( Gesture::State state, float x, float y );
/**
+ * @brief Creates a selection event.
+ *
+ * It could be called from the TapEvent (double tap) or when the text selection popup's sellect all button is pressed.
+ *
+ * @param[in] x The x position relative to the top-left of the parent control.
+ * @param[in] y The y position relative to the top-left of the parent control.
+ * @param[in] selectAll Whether the whole text is selected.
+ */
+ void SelectEvent( float x, float y, bool selectAll );
+
+ /**
* @brief Event received from input method context
*
* @param[in] inputMethodContext The input method context.
void TextDeletedEvent();
/**
- * @brief Creates a selection event.
- *
- * It could be called from the TapEvent (double tap) or when the text selection popup's sellect all button is pressed.
- *
- * @param[in] x The x position relative to the top-left of the parent control.
- * @param[in] y The y position relative to the top-left of the parent control.
- * @param[in] selectAll Whether the whole text is selected.
- */
- void SelectEvent( float x, float y, bool selectAll );
-
- /**
* @brief Helper to KeyEvent() to handle the backspace or delete key case.
*
* @param[in] keyCode The keycode for the key pressed
void AnimatedVectorImageVisual::GetNaturalSize( Vector2& naturalSize )
{
- naturalSize = mVisualSize;
+ if( mImpl->mRenderer ) // Check if we have a rendered image
+ {
+ auto textureSet = mImpl->mRenderer.GetTextures();
+ if( textureSet )
+ {
+ if( textureSet.GetTextureCount() > 0 )
+ {
+ auto texture = textureSet.GetTexture( 0 );
+ naturalSize.x = texture.GetWidth();
+ naturalSize.y = texture.GetHeight();
+ return;
+ }
+ }
+ }
+
+ uint32_t width, height;
+ mVectorRasterizeThread.GetDefaultSize( width, height );
+ naturalSize.x = width;
+ naturalSize.y = height;
}
void AnimatedVectorImageVisual::DoCreatePropertyMap( Property::Map& map ) const
mCurrentFrameUpdated( false ),
mLogFactory( Dali::Adaptor::Get().GetLogFactory() )
{
- mVectorRenderer = VectorAnimationRenderer::New( mUrl );
+ Initialize();
}
VectorRasterizeThread::~VectorRasterizeThread()
SetThreadName( "VectorImageThread" );
mLogFactory.InstallLogFunction();
- //TODO: check the return value
- StartRender();
-
while( !mDestroyThread )
{
Rasterize();
mPlayRange = orderedRange;
- if( mTotalFrame != 0 )
- {
- mStartFrame = static_cast< uint32_t >( mPlayRange.x * mTotalFrame + 0.5f );
- mEndFrame = static_cast< uint32_t >( mPlayRange.y * mTotalFrame + 0.5f );
+ mStartFrame = static_cast< uint32_t >( mPlayRange.x * mTotalFrame + 0.5f );
+ mEndFrame = static_cast< uint32_t >( mPlayRange.y * mTotalFrame + 0.5f );
- // If the current frame is out of the range, change the current frame also.
- if( mStartFrame > mCurrentFrame )
- {
- mCurrentFrame = mStartFrame;
+ // If the current frame is out of the range, change the current frame also.
+ if( mStartFrame > mCurrentFrame )
+ {
+ mCurrentFrame = mStartFrame;
- mCurrentFrameUpdated = true;
- mResourceReady = false;
- }
- else if( mEndFrame < mCurrentFrame )
- {
- mCurrentFrame = mEndFrame;
+ mCurrentFrameUpdated = true;
+ mResourceReady = false;
+ }
+ else if( mEndFrame < mCurrentFrame )
+ {
+ mCurrentFrame = mEndFrame;
- mCurrentFrameUpdated = true;
- mResourceReady = false;
- }
+ mCurrentFrameUpdated = true;
+ mResourceReady = false;
}
}
}
{
mProgress = progress;
- if( mTotalFrame != 0 )
- {
- mCurrentFrame = static_cast< uint32_t >( mTotalFrame * progress + 0.5f );
- mCurrentFrameUpdated = true;
- }
+ mCurrentFrame = static_cast< uint32_t >( mTotalFrame * progress + 0.5f );
+ mCurrentFrameUpdated = true;
mResourceReady = false;
return ( static_cast< float >( mCurrentFrame ) / static_cast< float >( mTotalFrame ) );
}
+void VectorRasterizeThread::GetDefaultSize( uint32_t& width, uint32_t& height ) const
+{
+ mVectorRenderer.GetDefaultSize( width, height );
+}
+
DevelImageVisual::PlayState VectorRasterizeThread::GetPlayState() const
{
return mPlayState;
return mResourceReady;
}
-bool VectorRasterizeThread::StartRender()
+void VectorRasterizeThread::Initialize()
{
- //TODO: check the return value
- mVectorRenderer.StartRender();
+ mVectorRenderer = VectorAnimationRenderer::New( mUrl );
mTotalFrame = mVectorRenderer.GetTotalFrameNumber();
mFrameRate = mVectorRenderer.GetFrameRate();
mFrameDurationNanoSeconds = NANOSECONDS_PER_SECOND / mFrameRate;
- DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::StartRender: Renderer is started [%d, %f fps]\n", mTotalFrame, mFrameRate );
-
- return true;
+ DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::Initialize: file = %s [%d frames, %f fps]\n", mUrl.c_str(), mTotalFrame, mFrameRate );
}
void VectorRasterizeThread::Rasterize()
*/
float GetCurrentProgress() const;
+ /**
+ * @brief Gets the default size of the file,.
+ * @return The default size of the file
+ */
+ void GetDefaultSize( uint32_t& width, uint32_t& height ) const;
+
protected:
/**
private:
/**
- * @brief Start rendering
+ * @brief Initialize the vector renderer.
*/
- bool StartRender();
+ void Initialize();
/**
* @brief Rasterize the current frame.
const unsigned int TOOLKIT_MAJOR_VERSION = 1;
const unsigned int TOOLKIT_MINOR_VERSION = 4;
-const unsigned int TOOLKIT_MICRO_VERSION = 14;
+const unsigned int TOOLKIT_MICRO_VERSION = 16;
const char * const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
~~~{.sh}
cd dali-adaptor/build/tizen
autoreconf --install
-./configure --prefix=$DESKTOP_PREFIX --enable-profile=UBUNTU --enable-gles=20
+./configure --prefix=$DESKTOP_PREFIX --enable-profile=UBUNTU
make install -j8
~~~
Here is an example dali-adaptor configure line:
~~~
-$ CXXFLAGS="-g -O0 -Wno-unused-local-typedefs" CXX="ccache g++" ./configure --prefix=$DESKTOP_PREFIX --enable-debug=yes --enable-profile=UBUNTU --enable-gles=20 --enable-networklogging
+$ CXXFLAGS="-g -O0 -Wno-unused-local-typedefs" CXX="ccache g++" ./configure --prefix=$DESKTOP_PREFIX --enable-debug=yes --enable-profile=UBUNTU --enable-networklogging
~~~
Once this RPM is installed, you can run your DALi application and connect Stagehand to it.
Name: dali-toolkit
Summary: Dali 3D engine Toolkit
-Version: 1.4.14
+Version: 1.4.16
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-3-Clause and MIT