{
"config":
{
- "alwaysShowFocus":false
+ "alwaysShowFocus":false,
+ "clearFocusOnEscape":true
},
"constants":
{
#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
#include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
#include <dali-toolkit/devel-api/visual-factory/visual-base.h>
+#include <dali-toolkit/public-api/styling/style-manager.h>
+#include <dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h>
+#include <dali-toolkit/devel-api/styling/style-manager-devel.h>
+#include <dali/integration-api/events/key-event-integ.h>
using namespace Dali;
using namespace Dali::Toolkit;
END_TEST;
}
+
+
+int UtcDaliStyleManagerConfigSectionTest(void)
+{
+ tet_infoline("Test that the properties in config section are works" );
+
+ const char* defaultTheme =
+ "{\n"
+ " \"config\":\n"
+ " {\n"
+ " \"alwaysShowFocus\":false,\n"
+ " \"clearFocusOnEscape\":false\n"
+ " },\n"
+ " \"styles\":\n"
+ " {\n"
+ " }\n"
+ "}\n";
+
+ Test::StyleMonitor::SetThemeFileOutput( DALI_STYLE_DIR "dali-toolkit-default-theme.json", defaultTheme );
+
+ ToolkitTestApplication application;
+
+ Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
+
+ Property::Map config = Toolkit::DevelStyleManager::GetConfigurations( styleManager );
+ bool alwaysShowFocus = config["alwaysShowFocus"].Get<bool>();
+ DALI_TEST_CHECK( !alwaysShowFocus );
+ bool clearFocusOnEscape = config["clearFocusOnEscape"].Get<bool>();
+ DALI_TEST_CHECK( !clearFocusOnEscape );
+
+ // For coverage
+ Toolkit::TextEditor editor = Toolkit::TextEditor::New();
+ editor.SetKeyboardFocusable( true );
+ Stage::GetCurrent().Add( editor );
+
+ Toolkit::KeyboardFocusManager::Get().SetCurrentFocusActor( editor );
+
+ application.ProcessEvent( Integration::KeyEvent( "", "", DALI_KEY_ESCAPE, 0, 0, Integration::KeyEvent::Down, "", DevelDevice::Class::NONE, DevelDevice::Subclass::NONE ) );
+ application.SendNotification();
+ application.Render();
+
+ END_TEST;
+}
}
END_TEST;
}
+
+int UtcDaliTextFieldDefaultFontStylePropertyCoverage(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliTextFieldFontStylePorpertyCoverage");
+ TextField field = TextField::New();
+ DALI_TEST_CHECK( field );
+ Stage::GetCurrent().Add( field );
+
+ Property::Map fontStyleMapGet;
+
+ fontStyleMapGet = field.GetProperty<Property::Map>( TextField::Property::FONT_STYLE );
+
+ Property::Value* weightValue = NULL;
+ Property::Value* widthValue = NULL;
+ Property::Value* slantValue = NULL;
+ weightValue = fontStyleMapGet.Find( "weight" );
+ widthValue = fontStyleMapGet.Find( "width" );
+ slantValue = fontStyleMapGet.Find( "slant" );
+ DALI_TEST_CHECK( !weightValue );
+ DALI_TEST_CHECK( !widthValue );
+ DALI_TEST_CHECK( !slantValue );
+
+ END_TEST;
+}
SUBDIRS += docs
pkgconfigdir = $(libdir)/pkgconfig
+
pkgconfig_DATA = dali-toolkit.pc
MAINTAINERCLEANFILES = \
@test -z $(COVERAGE_DIR) || mkdir -p $(COVERAGE_DIR)
@rm -f $(COVERAGE_DIR)/*
@cp dali-toolkit/.libs/*.gcda dali-toolkit/.libs/*.gcno $(COVERAGE_DIR)
- @for i in `find $(COVERAGE_DIR) -name "libdali_toolkit_la-*.gcda" -o -name "libdali_toolkit_la-*.gcno"` ;\
- do mv $$i `echo $$i | sed s/libdali_toolkit_la-//` ; echo $$i ; done
+ @for i in `find $(COVERAGE_DIR) -name "libdali_toolkit*_la-*.gcda" -o -name "libdali_toolkit*_la-*.gcno"` ;\
+ do mv $$i `echo $$i | sed s/libdali_toolkit*_la-//` ; echo $$i ; done
cov_data: rename_cov_data
@cd $(COVERAGE_DIR) ; lcov $(LCOV_OPTS) --base-directory . --directory . -c -o dali.info
DALI_TOOLKIT_VERSION=dali_version
AC_SUBST(DALI_TOOLKIT_VERSION)
-PKG_CHECK_MODULES(DALICORE, dali-core)
DALI_TOOLKIT_CFLAGS=-DPLATFORM_TIZEN
[enable_csharp=$enableval],
[enable_csharp=automatic])
+AC_ARG_ENABLE([cxx03_abi],
+ [AC_HELP_STRING([--enable-cxx03-abi],
+ [Specify abi for the build])],
+ [enable_cxx03_abi=$enableval],
+ [enable_cxx03_abi=no])
+
+AC_ARG_ENABLE([rename_so],
+ [AC_HELP_STRING([--enable-rename-so],
+ [Specify whether so file is renamed or not])],
+ [enable_rename_so=$enableval],
+ [enable_rename_so=yes])
+
+AM_CONDITIONAL([ENABLE_CXX03_ABI], [test x$enable_cxx03_abi = xyes])
+AM_CONDITIONAL([ENABLE_RENAME_SO], [test x$enable_rename_so = xyes])
+
+if test "x$enable_cxx03_abi" = "xyes"; then
+ DALI_TOOLKIT_CFLAGS="$DALI_TOOLKIT_CFLAGS -D_GLIBCXX_USE_CXX11_ABI=0"
+fi
+
if test "x$enable_debug" = "xyes"; then
DALI_TOOLKIT_CFLAGS="$DALI_TOOLKIT_CFLAGS -DDEBUG_ENABLED"
fi
AC_SUBST(DALITOOLKIT_LIBS)
fi
+if test "x$enable_cxx03_abi" = "xyes"; then
+PKG_CHECK_MODULES(DALICORE, dali-core-cxx03)
+else
+PKG_CHECK_MODULES(DALICORE, dali-core)
+fi
+
#set a variable for the makefile to force compile the csharp plugin
AM_CONDITIONAL([ENABLE_CSHARP_PLUGIN], [test x$build_csharp_plugin = xyes])
AM_CONDITIONAL([ENABLE_RUBY_FLAG], [test x$build_ruby_flag = xyes])
dali-toolkit/Makefile
plugins/javascript/Makefile
plugins/csharp/Makefile
- dali-toolkit.pc
docs/Makefile
docs/dali.doxy
docs-internal/dali-internal.doxy
../../automated-tests/CMakeLists.txt
])
+if test "x$enable_cxx03_abi" = "xno"; then
+AC_CONFIG_FILES([dali-toolkit.pc])
+fi
+
AC_OUTPUT
echo "
libdir=@libdir@
includedir=@devincludepath@
-Name: Samsung OpenGLES Toolkit (including Toolkit)
-Description: 3D Canvas Toolkit using OpenGLES (with the toolkit)
+Name: Dali 3D engine Toolkit
+Description: Cross platform 3D Engine Toolkit
Version: ${apiversion}
Requires: dali-core
Libs: -L${libdir} -ldali-toolkit
package_doxy_dir = ../../../doc
include ../../../doc/file.list
-# The library
-lib_LTLIBRARIES = libdali-toolkit.la
-
-libdali_toolkit_la_SOURCES = \
+LIBDALI_TOOLKIT_LA_SOURCES = \
$(toolkit_src_files) \
$(public_api_src_files) \
$(devel_api_src_files) \
libdali_toolkit_la_DEPENDENCIES =
-libdali_toolkit_la_CXXFLAGS = -DDALI_COMPILATION \
+LIBDALI_TOOLKIT_LA_CXXFLAGS = -DDALI_COMPILATION \
-DDALI_IMAGE_DIR="\"${daliimagedir}\"" \
-DDALI_SOUND_DIR="\"${dalisounddir}\"" \
-DDALI_STYLE_DIR="\"${dalistyledir}\"" \
$(FRIBIDI_CFLAGS) \
$(HTMLCXX_CFLAGS)
-libdali_toolkit_la_LIBADD = \
+LIBDALI_TOOLKIT_LA_LIBADD = \
$(DALICORE_LIBS) \
$(DLOG_LIBS) \
$(FRIBIDI_LIBS) \
$(HTMLCXX_LIBS)
-# Install headers
+# The library
+if ENABLE_CXX03_ABI
+
+lib_LTLIBRARIES = libdali-toolkit.la
+libdali_toolkit_la_SOURCES = $(LIBDALI_TOOLKIT_LA_SOURCES)
+libdali_toolkit_la_LIBADD = $(LIBDALI_TOOLKIT_LA_LIBADD)
+libdali_toolkit_la_CXXFLAGS = $(LIBDALI_TOOLKIT_LA_CXXFLAGS)
+libdali_toolkit_la_CFLAGS = $(LIBDALI_TOOLKTI_LA_CFLAGS)
+
+if ENABLE_RENAME_SO
+#rename
+install: install-am
+ rm -rf $(libdir)/libdali-toolkit.so
+ rm -rf $(libdir)/libdali-toolkit-cxx03.so
+ ln -s $(libdir)/libdali-toolkit.so.0.0.* $(libdir)/libdali-toolkit-cxx03.so
+endif
+
+else
+
+lib_LTLIBRARIES = libdali-toolkit-cxx11.la
+libdali_toolkit_cxx11_la_SOURCES = $(LIBDALI_TOOLKIT_LA_SOURCES)
+libdali_toolkit_cxx11_la_LIBADD = $(LIBDALI_TOOLKIT_LA_LIBADD)
+libdali_toolkit_cxx11_la_CXXFLAGS = $(LIBDALI_TOOLKIT_LA_CXXFLAGS)
+libdali_toolkit_cxx11_la_CFLAGS = $(LIBDALI_TOOLKTI_LA_CFLAGS)
+
+if ENABLE_RENAME_SO
+#rename
+install: install-am
+ rm -rf $(libdir)/libdali-toolkit-cxx11.so
+ rm -rf $(libdir)/libdali-toolkit.so
+ ln -s $(libdir)/libdali-toolkit-cxx11.so.0.0.* $(libdir)/libdali-toolkit.so
+endif
+
+endif
+
+# Install headers
topleveldir = $(devincludepath)/dali-toolkit
toplevel_HEADERS = ../../../dali-toolkit/dali-toolkit.h
DALI_PROPERTY_REGISTRATION( Toolkit, TableView, "layoutRows", MAP, LAYOUT_ROWS )
DALI_PROPERTY_REGISTRATION( Toolkit, TableView, "layoutColumns", MAP, LAYOUT_COLUMNS )
DALI_CHILD_PROPERTY_REGISTRATION( Toolkit, TableView, "cellIndex", VECTOR2, CELL_INDEX )
-DALI_CHILD_PROPERTY_REGISTRATION( Toolkit, TableView, "rowSpan", FLOAT, ROW_SPAN )
-DALI_CHILD_PROPERTY_REGISTRATION( Toolkit, TableView, "columnSpan", FLOAT, COLUMN_SPAN )
+DALI_CHILD_PROPERTY_REGISTRATION( Toolkit, TableView, "rowSpan", INTEGER, ROW_SPAN )
+DALI_CHILD_PROPERTY_REGISTRATION( Toolkit, TableView, "columnSpan", INTEGER, COLUMN_SPAN )
DALI_CHILD_PROPERTY_REGISTRATION( Toolkit, TableView, "cellHorizontalAlignment", STRING, CELL_HORIZONTAL_ALIGNMENT )
DALI_CHILD_PROPERTY_REGISTRATION( Toolkit, TableView, "cellVerticalAlignment", STRING, CELL_VERTICAL_ALIGNMENT )
Toolkit::TableView::CellPosition cellPosition;
if( child.GetPropertyType( Toolkit::TableView::ChildProperty::ROW_SPAN ) != Property::NONE )
{
- cellPosition.rowSpan = static_cast<unsigned int>( child.GetProperty( Toolkit::TableView::ChildProperty::ROW_SPAN ).Get<float>() );
+ cellPosition.rowSpan = child.GetProperty( Toolkit::TableView::ChildProperty::ROW_SPAN ).Get< int >();
}
if( child.GetPropertyType( Toolkit::TableView::ChildProperty::COLUMN_SPAN ) != Property::NONE )
{
- cellPosition.columnSpan = static_cast<unsigned int>( child.GetProperty( Toolkit::TableView::ChildProperty::COLUMN_SPAN ).Get<float>() );
+ cellPosition.columnSpan = child.GetProperty( Toolkit::TableView::ChildProperty::COLUMN_SPAN ).Get< int >();
}
if( child.GetPropertyType( Toolkit::TableView::ChildProperty::CELL_INDEX ) != Property::NONE )
{
DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnKeyEvent %p keyCode %d\n", mController.Get(), event.keyCode );
- if( Dali::DALI_KEY_ESCAPE == event.keyCode ) // Make a Dali key code for this
+ if( Dali::DALI_KEY_ESCAPE == event.keyCode && mController->ShouldClearFocusOnEscape() )
{
// Make sure ClearKeyInputFocus when only key is up
if( event.state == KeyEvent::Up )
{
DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnKeyEvent %p keyCode %d\n", mController.Get(), event.keyCode );
- if( Dali::DALI_KEY_ESCAPE == event.keyCode ) // Make a Dali key code for this
+ if( Dali::DALI_KEY_ESCAPE == event.keyCode && mController->ShouldClearFocusOnEscape() )
{
// Make sure ClearKeyInputFocus when only key is up
if( event.state == KeyEvent::Up )
// Create a texture of the text for scrolling
Text::TypesetterPtr typesetter = Text::Typesetter::New( mController->GetTextModel() );
- PixelData data = typesetter->Render( textNaturalSize, Text::Typesetter::RENDER_TEXT_AND_STYLES, true ); // ignore the horizontal alignment
+ PixelData data = typesetter->Render( textNaturalSize, Text::Typesetter::RENDER_TEXT_AND_STYLES, true, Pixel::RGBA8888 ); // ignore the horizontal alignment
Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D,
data.GetPixelFormat(),
data.GetWidth(),
--- /dev/null
+
+#ifndef DALI_TOOLKIT_INTERNAL_ROUND_ROBIN_CONTAINER_VIEW_H
+#define DALI_TOOLKIT_INTERNAL_ROUND_ROBIN_CONTAINER_VIEW_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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <cstddef>
+#include <vector>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+/**
+ * @brief RoundRobinContainerView is a view to a container that allows iterating through the elements cyclically.
+ */
+template<typename T>
+class RoundRobinContainerView
+{
+public:
+ using ContainerType = std::vector<T>;
+
+ /**
+ * @brief Constructs a new RoundRobinControlView with the given number elements using the provided factory.
+ * @param[in] numberOfElements The number of elements in the container
+ * @param[in] factory Factory function of functor that will be used to create instances of the elements
+ */
+ template<typename FactoryType>
+ RoundRobinContainerView(size_t numberOfElements, const FactoryType& factory)
+ : mElements(),
+ mNextIndex{}
+ {
+ mElements.reserve(numberOfElements);
+ for(unsigned i = {}; i < numberOfElements; ++i)
+ {
+ mElements.push_back(factory());
+ }
+ }
+
+ /**
+ * @brief Reset the position of the iterator returned by GetNext() to the first element.
+ */
+ void Reset()
+ {
+ mNextIndex = 0u;
+ }
+
+ /**
+ * @brief Returns the next element on the container.
+ * @return Iterator for the next element
+ */
+ typename ContainerType::iterator GetNext()
+ {
+ SetValidNextIndex();
+
+ return mElements.begin() + mNextIndex++;
+ }
+
+ /**
+ * @brief Returns the iterator to the end of the container.
+ *
+ * Can be used to compare against GetNext() to check if the container is empty.
+ *
+ * @return The container end() element
+ */
+ typename ContainerType::const_iterator End() const
+ {
+ return mElements.cend();
+ }
+
+ // default members
+ ~RoundRobinContainerView() = default;
+
+ RoundRobinContainerView(const RoundRobinContainerView&) = delete;
+ RoundRobinContainerView& operator=(const RoundRobinContainerView&) = delete;
+ RoundRobinContainerView(RoundRobinContainerView&&) = default;
+ RoundRobinContainerView& operator=(RoundRobinContainerView&&) = default;
+
+private:
+ /**
+ * @brief Check the current index and reset if necessary.
+ */
+ void SetValidNextIndex()
+ {
+ if(mNextIndex >= mElements.size())
+ {
+ Reset();
+ }
+ }
+
+private:
+ ContainerType mElements; //< container of elements
+ size_t mNextIndex; //< index to the next element to be viewed
+};
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+
+#endif // DALI_TOOLKIT_INTERNAL_ROUND_ROBIN_CONTAINER_VIEW_H
namespace
{
+#if _GLIBCXX_USE_CXX11_ABI
+const char* PLUGIN_FILE = "libdali-script-plugin-v8-cxx11.so";
+#else
const char* PLUGIN_FILE = "libdali-script-plugin-v8.so";
+#endif
}
Script::Script()
* @param[in] position The position of the glyph.
* @param[in] color The color of the glyph.
* @param[in] style The style of the text.
+ * @param[in] pixelFormat The format of the pixel in the image that the text is rendered as (i.e. either Pixel::BGRA8888 or Pixel::L8).
*/
void TypesetGlyph( GlyphData& data,
const Vector2* const position,
const Vector4* const color,
- Typesetter::Style style)
+ Typesetter::Style style,
+ Pixel::Format pixelFormat )
{
if( ( 0u == data.glyphBitmap.width ) || ( 0u == data.glyphBitmap.height ) )
{
const int widthMinusOne = static_cast<int>( data.width - 1u );
const int heightMinusOne = static_cast<int>( data.height - 1u );
- // Whether the given glyph is a color one.
- const bool isColorGlyph = 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;
+ if ( Pixel::RGBA8888 == pixelFormat )
+ {
+ // Whether the given glyph is a color one.
+ const bool isColorGlyph = Pixel::BGRA8888 == data.glyphBitmap.format;
- // Pack the given color into a 32bit buffer. The alpha channel will be updated later for each pixel.
- // The format is RGBA8888.
- uint32_t packedColor = 0u;
- uint8_t* packedColorBuffer = reinterpret_cast<uint8_t*>( &packedColor );
- *( packedColorBuffer + 2 ) = static_cast<uint8_t>( color->b * 255.f );
- *( packedColorBuffer + 1 ) = static_cast<uint8_t>( color->g * 255.f );
- *packedColorBuffer = static_cast<uint8_t>( color->r * 255.f );
+ // 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;
+ // Pack the given color into a 32bit buffer. The alpha channel will be updated later for each pixel.
+ // The format is RGBA8888.
+ uint32_t packedColor = 0u;
+ uint8_t* packedColorBuffer = reinterpret_cast<uint8_t*>( &packedColor );
+ *( packedColorBuffer + 2 ) = static_cast<uint8_t>( color->b * 255.f );
+ *( packedColorBuffer + 1 ) = static_cast<uint8_t>( color->g * 255.f );
+ *packedColorBuffer = static_cast<uint8_t>( color->r * 255.f );
- // Traverse the pixels of the glyph line per line.
- for( int lineIndex = 0, glyphHeight = static_cast<int>( data.glyphBitmap.height ); lineIndex < glyphHeight; ++lineIndex )
- {
- const int yOffsetIndex = yOffset + lineIndex;
- if( ( 0 > yOffsetIndex ) || ( yOffsetIndex > heightMinusOne ) )
- {
- // Do not write out of bounds.
- break;
- }
+ // Initial vertical offset.
+ const int yOffset = data.verticalOffset + position->y;
- const int verticalOffset = yOffsetIndex * data.width;
- const int xOffset = data.horizontalOffset + position->x;
- const int glyphBufferOffset = lineIndex * static_cast<int>( data.glyphBitmap.width );
- for( int index = 0, glyphWidth = static_cast<int>( data.glyphBitmap.width ); index < glyphWidth; ++index )
+ // Traverse the pixels of the glyph line per line.
+ for( int lineIndex = 0, glyphHeight = static_cast<int>( data.glyphBitmap.height ); lineIndex < glyphHeight; ++lineIndex )
{
- const int xOffsetIndex = xOffset + index;
- if( ( 0 > xOffsetIndex ) || ( xOffsetIndex > widthMinusOne ) )
+ const int yOffsetIndex = yOffset + lineIndex;
+ if( ( 0 > yOffsetIndex ) || ( yOffsetIndex > heightMinusOne ) )
{
- // Don't write out of bounds.
+ // Do not write out of bounds.
break;
}
- uint32_t* bitmapBuffer = reinterpret_cast< uint32_t* >( data.bitmapBuffer.GetBuffer() );
-
- if( isColorGlyph )
+ const int verticalOffset = yOffsetIndex * data.width;
+ const int xOffset = data.horizontalOffset + position->x;
+ const int glyphBufferOffset = lineIndex * static_cast<int>( data.glyphBitmap.width );
+ for( int index = 0, glyphWidth = static_cast<int>( data.glyphBitmap.width ); index < glyphWidth; ++index )
{
- // Retrieves the color from the color glyph. The format is BGRA8888.
- uint32_t packedColorGlyph = *( colorGlyphBuffer + glyphBufferOffset + index );
- uint8_t* packedColorGlyphBuffer = reinterpret_cast<uint8_t*>( &packedColorGlyph );
-
- if( Typesetter::STYLE_SHADOW == style )
+ const int xOffsetIndex = xOffset + index;
+ if( ( 0 > xOffsetIndex ) || ( xOffsetIndex > widthMinusOne ) )
{
- // The shadow of color glyph needs to have the shadow color.
- *( packedColorGlyphBuffer + 2 ) = static_cast<uint8_t>( color->b * 255.f );
- *( packedColorGlyphBuffer + 1 ) = static_cast<uint8_t>( color->g * 255.f );
- *packedColorGlyphBuffer = static_cast<uint8_t>( color->r * 255.f );
- }
- else
- {
- std::swap( *packedColorGlyphBuffer, *( packedColorGlyphBuffer + 2u ) ); // Swap B and R.
+ // Don't write out of bounds.
+ break;
}
- // Update the alpha channel.
- if( Typesetter::STYLE_MASK == style )
+ uint32_t* bitmapBuffer = reinterpret_cast< uint32_t* >( data.bitmapBuffer.GetBuffer() );
+
+ if( isColorGlyph )
{
- // Create an alpha mask for color glyph.
- *( packedColorGlyphBuffer + 3u ) = 0u;
+ // Retrieves the color from the color glyph. The format is BGRA8888.
+ uint32_t packedColorGlyph = *( colorGlyphBuffer + glyphBufferOffset + index );
+ uint8_t* packedColorGlyphBuffer = reinterpret_cast<uint8_t*>( &packedColorGlyph );
+
+ if( Typesetter::STYLE_SHADOW == style )
+ {
+ // The shadow of color glyph needs to have the shadow color.
+ *( packedColorGlyphBuffer + 2 ) = static_cast<uint8_t>( color->b * 255.f );
+ *( packedColorGlyphBuffer + 1 ) = static_cast<uint8_t>( color->g * 255.f );
+ *packedColorGlyphBuffer = static_cast<uint8_t>( color->r * 255.f );
+ }
+ else
+ {
+ std::swap( *packedColorGlyphBuffer, *( packedColorGlyphBuffer + 2u ) ); // Swap B and R.
+ }
+
+ // Update the alpha channel.
+ if( Typesetter::STYLE_MASK == style )
+ {
+ // Create an alpha mask for color glyph.
+ *( packedColorGlyphBuffer + 3u ) = 0u;
+ }
+ else
+ {
+ *( packedColorGlyphBuffer + 3u ) = static_cast<uint8_t>( color->a * static_cast<float>( *( packedColorGlyphBuffer + 3u ) ) );
+ }
+
+ // Set the color into the final pixel buffer.
+ *( bitmapBuffer + verticalOffset + xOffsetIndex ) = packedColorGlyph;
}
else
{
- *( packedColorGlyphBuffer + 3u ) = static_cast<uint8_t>( color->a * static_cast<float>( *( packedColorGlyphBuffer + 3u ) ) );
+ // Update the alpha channel.
+ const uint8_t alpha = *( data.glyphBitmap.buffer + glyphBufferOffset + index );
+
+ // Copy non-transparent pixels only
+ if ( alpha > 0u )
+ {
+ // Check alpha of overlapped pixels
+ uint32_t& currentColor = *( bitmapBuffer + verticalOffset + xOffsetIndex );
+ uint8_t* packedCurrentColorBuffer = reinterpret_cast<uint8_t*>( ¤tColor );
+
+ uint8_t currentAlpha = *( packedCurrentColorBuffer + 3u );
+ uint8_t newAlpha = static_cast<uint8_t>( color->a * static_cast<float>( alpha ) );
+
+ // For any pixel overlapped with the pixel in previous glyphs, make sure we don't
+ // overwrite a previous bigger alpha with a smaller alpha (in order to avoid
+ // semi-transparent gaps between joint glyphs with overlapped pixels, which could
+ // happen, for example, in the RTL text when we copy glyphs from right to left).
+ *( packedColorBuffer + 3u ) = std::max( currentAlpha, newAlpha );
+
+ // Set the color into the final pixel buffer.
+ currentColor = packedColor;
+ }
}
+ }
+ }
+ }
+ else
+ {
+ // Initial vertical offset.
+ const int yOffset = data.verticalOffset + position->y;
- // Set the color into the final pixel buffer.
- *( bitmapBuffer + verticalOffset + xOffsetIndex ) = packedColorGlyph;
+ // Traverse the pixels of the glyph line per line.
+ for( int lineIndex = 0, glyphHeight = static_cast<int>( data.glyphBitmap.height ); lineIndex < glyphHeight; ++lineIndex )
+ {
+ const int yOffsetIndex = yOffset + lineIndex;
+ if( ( 0 > yOffsetIndex ) || ( yOffsetIndex > heightMinusOne ) )
+ {
+ // Do not write out of bounds.
+ break;
}
- else
+
+ const int verticalOffset = yOffsetIndex * data.width;
+ const int xOffset = data.horizontalOffset + position->x;
+ const int glyphBufferOffset = lineIndex * static_cast<int>( data.glyphBitmap.width );
+ for( int index = 0, glyphWidth = static_cast<int>( data.glyphBitmap.width ); index < glyphWidth; ++index )
{
+ const int xOffsetIndex = xOffset + index;
+ if( ( 0 > xOffsetIndex ) || ( xOffsetIndex > widthMinusOne ) )
+ {
+ // Don't write out of bounds.
+ break;
+ }
+
+ uint8_t* bitmapBuffer = reinterpret_cast< uint8_t* >( data.bitmapBuffer.GetBuffer() );
+
// Update the alpha channel.
const uint8_t alpha = *( data.glyphBitmap.buffer + glyphBufferOffset + index );
if ( alpha > 0u )
{
// Check alpha of overlapped pixels
- uint32_t& currentColor = *( bitmapBuffer + verticalOffset + xOffsetIndex );
- uint8_t* packedCurrentColorBuffer = reinterpret_cast<uint8_t*>( ¤tColor );
-
- uint8_t currentAlpha = *( packedCurrentColorBuffer + 3u );
+ uint8_t& currentAlpha = *( bitmapBuffer + verticalOffset + xOffsetIndex );
uint8_t newAlpha = static_cast<uint8_t>( color->a * static_cast<float>( alpha ) );
+// printf("y: %d, x: %d: alpha: %u, currentAlpha: %u, newAlpha: %u, a: %u\n", yOffsetIndex, xOffsetIndex, alpha, currentAlpha, newAlpha, std::max( currentAlpha, newAlpha ) );
// For any pixel overlapped with the pixel in previous glyphs, make sure we don't
// overwrite a previous bigger alpha with a smaller alpha (in order to avoid
// semi-transparent gaps between joint glyphs with overlapped pixels, which could
// happen, for example, in the RTL text when we copy glyphs from right to left).
- *( packedColorBuffer + 3u ) = std::max( currentAlpha, newAlpha );
-
- // Set the color into the final pixel buffer.
- currentColor = packedColor;
+ *( bitmapBuffer + verticalOffset + xOffsetIndex ) = std::max( currentAlpha, newAlpha );
}
}
}
return mModel;
}
-PixelData Typesetter::Render( const Vector2& size, RenderBehaviour behaviour, bool ignoreHorizontalAlignment )
+PixelData Typesetter::Render( const Vector2& size, RenderBehaviour behaviour, bool ignoreHorizontalAlignment, Pixel::Format pixelFormat )
{
// @todo. This initial implementation for a TextLabel has only one visible page.
if( RENDER_MASK == behaviour )
{
// Generate the image buffer as an alpha mask for color glyphs.
- imageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_MASK, ignoreHorizontalAlignment, penY, 0u, numberOfGlyphs - 1 );
+ imageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_MASK, ignoreHorizontalAlignment, pixelFormat, penY, 0u, numberOfGlyphs - 1 );
}
else if( RENDER_NO_TEXT == behaviour )
{
else
{
// Generate the image buffer for the text with no style.
- imageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_NONE, ignoreHorizontalAlignment, penY, 0u, numberOfGlyphs -1 );
+ imageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_NONE, ignoreHorizontalAlignment, pixelFormat, penY, 0u, numberOfGlyphs -1 );
}
if ( ( RENDER_NO_STYLES != behaviour ) && ( RENDER_MASK != behaviour ) )
if ( fabsf( shadowOffset.x ) > Math::MACHINE_EPSILON_1 || fabsf( shadowOffset.y ) > Math::MACHINE_EPSILON_1 )
{
// Create the image buffer for shadow
- Devel::PixelBuffer shadowImageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_SHADOW, ignoreHorizontalAlignment, penY, 0u, numberOfGlyphs - 1 );
+ Devel::PixelBuffer shadowImageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_SHADOW, ignoreHorizontalAlignment, pixelFormat, penY, 0u, numberOfGlyphs - 1 );
// Combine the two buffers
imageBuffer = CombineImageBuffer( imageBuffer, shadowImageBuffer, bufferWidth, bufferHeight );
if ( underlineEnabled )
{
// Create the image buffer for underline
- Devel::PixelBuffer underlineImageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_UNDERLINE, ignoreHorizontalAlignment, penY, 0u, numberOfGlyphs - 1 );
+ Devel::PixelBuffer underlineImageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_UNDERLINE, ignoreHorizontalAlignment, pixelFormat, penY, 0u, numberOfGlyphs - 1 );
// Combine the two buffers
imageBuffer = CombineImageBuffer( imageBuffer, underlineImageBuffer, bufferWidth, bufferHeight );
return pixelData;
}
-Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth, const unsigned int bufferHeight, Typesetter::Style style, bool ignoreHorizontalAlignment, int verticalOffset, GlyphIndex fromGlyphIndex, GlyphIndex toGlyphIndex )
+Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth, const unsigned int bufferHeight, Typesetter::Style style, bool ignoreHorizontalAlignment, Pixel::Format pixelFormat, int verticalOffset, GlyphIndex fromGlyphIndex, GlyphIndex toGlyphIndex )
{
// Retrieve lines, glyphs, positions and colors from the view model.
const Length modelNumberOfLines = mModel->GetNumberOfLines();
// Create and initialize the pixel buffer.
GlyphData glyphData;
glyphData.verticalOffset = verticalOffset;
-
glyphData.width = bufferWidth;
glyphData.height = bufferHeight;
- const unsigned int bufferSizeInt = bufferWidth * bufferHeight;
- const unsigned int bufferSizeChar = 4u * bufferSizeInt;
- glyphData.bitmapBuffer = Devel::PixelBuffer::New( bufferWidth, bufferHeight, Pixel::RGBA8888 );
- memset( glyphData.bitmapBuffer.GetBuffer(), 0u, bufferSizeChar );
+ glyphData.bitmapBuffer = Devel::PixelBuffer::New( bufferWidth, bufferHeight, pixelFormat );
+
+ if ( Pixel::RGBA8888 == pixelFormat )
+ {
+ const unsigned int bufferSizeInt = bufferWidth * bufferHeight;
+ const unsigned int bufferSizeChar = 4u * bufferSizeInt;
+ memset( glyphData.bitmapBuffer.GetBuffer(), 0u, bufferSizeChar );
+ }
+ else
+ {
+ memset( glyphData.bitmapBuffer.GetBuffer(), 0, bufferWidth * bufferHeight );
+ }
// Get a handle of the font client. Used to retrieve the bitmaps of the glyphs.
TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
TypesetGlyph( glyphData,
position,
color,
- style );
+ style,
+ pixelFormat);
// delete the glyphBitmap.buffer as it is now copied into glyphData.bitmapBuffer
delete []glyphData.glyphBitmap.buffer;
glyphData.glyphBitmap.buffer = NULL;
break;
}
+ // Always RGBA image for text with styles
uint32_t* bitmapBuffer = reinterpret_cast< uint32_t* >( glyphData.bitmapBuffer.GetBuffer() );
uint32_t underlinePixel = *( bitmapBuffer + y * glyphData.width + x );
uint8_t* underlinePixelBuffer = reinterpret_cast<uint8_t*>( &underlinePixel );
return topPixelBuffer;
}
+ // Always combine two RGBA images
const unsigned int bufferSizeInt = bufferWidth * bufferHeight;
const unsigned int bufferSizeChar = 4u * bufferSizeInt;
// EXTERNAL INCLUDES
#include <dali/public-api/common/intrusive-ptr.h>
#include <dali/public-api/object/ref-object.h>
+#include <dali/public-api/images/pixel.h>
#include <dali/public-api/images/pixel-data.h>
#include <dali/devel-api/text-abstraction/text-abstraction-definitions.h>
#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
* @param[in] size The renderer size.
* @param[in] behaviour The behaviour of how to render the text (i.e. whether to render the text only or the styles only or both).
* @param[in] ignoreHorizontalAlignment Whether to ignore the horizontal alignment (i.e. always render as if HORIZONTAL_ALIGN_BEGIN).
+ * @param[in] pixelFormat The format of the pixel in the image that the text is rendered as (i.e. either Pixel::BGRA8888 or Pixel::L8).
*
* @return A pixel data with the text rendered.
*/
- PixelData Render( const Vector2& size, RenderBehaviour behaviour = RENDER_TEXT_AND_STYLES, bool ignoreHorizontalAlignment = false );
+ PixelData Render( const Vector2& size, RenderBehaviour behaviour = RENDER_TEXT_AND_STYLES, bool ignoreHorizontalAlignment = false, Pixel::Format pixelFormat = Pixel::RGBA8888 );
private:
/**
* @param[in] bufferHeight The height of the image buffer.
* @param[in] style The style of the text.
* @param[in] ignoreHorizontalAlignment Whether to ignore the horizontal alignment, not ignored by default.
+ * @param[in] pixelFormat The format of the pixel in the image that the text is rendered as (i.e. either Pixel::BGRA8888 or Pixel::L8).
* @param[in] verticalOffset The vertical offset to be added to the glyph's position.
* @param[in] fromGlyphIndex The index of the first glyph within the text to be drawn
* @param[in] toGlyphIndex The index of the last glyph within the text to be drawn
*
* @return An image buffer with the text.
*/
- Devel::PixelBuffer CreateImageBuffer( const unsigned int bufferWidth, const unsigned int bufferHeight, Typesetter::Style style, bool ignoreHorizontalAlignment, int verticalOffset, TextAbstraction::GlyphIndex fromGlyphIndex, TextAbstraction::GlyphIndex toGlyphIndex );
+ Devel::PixelBuffer CreateImageBuffer( const unsigned int bufferWidth, const unsigned int bufferHeight, Typesetter::Style style, bool ignoreHorizontalAlignment, Pixel::Format pixelFormat, int verticalOffset, TextAbstraction::GlyphIndex fromGlyphIndex, TextAbstraction::GlyphIndex toGlyphIndex );
/**
- * @brief Combine the two image buffers together.
+ * @brief Combine the two RGBA image buffers together.
*
* The top layer buffer will blend over the bottom layer buffer:
* - If the pixel is not fully opaque from either buffer, it will be blended with
* @return The combined image buffer with the text.
*
*/
- Devel::PixelBuffer CombineImageBuffer( Devel::PixelBuffer topPixelBuffer, Devel::PixelBuffer bottomPixelBuffer, const unsigned int bufferWidth, const unsigned int bufferHeight );
+ Devel::PixelBuffer CombineImageBuffer( Devel::PixelBuffer topPixelBuffer, Devel::PixelBuffer bottomPixelBuffer, const unsigned int bufferWidth, const unsigned int bufferHeightbool );
protected:
return mModel->GetLines();
}
+Length ViewModel::GetNumberOfScripts() const
+{
+ return mModel->GetNumberOfScripts();
+}
+
+const ScriptRun* const ViewModel::GetScriptRuns() const
+{
+ return mModel->GetScriptRuns();
+}
+
Length ViewModel::GetNumberOfGlyphs() const
{
if( mIsTextElided && mModel->IsTextElideEnabled() )
virtual const LineRun* const GetLines() const;
/**
+ * @copydoc ModelInterface::GetNumberOfScripts()
+ */
+ virtual Length GetNumberOfScripts() const;
+
+ /**
+ * @copydoc ModelInterface::GetScriptRuns()
+ */
+ virtual const ScriptRun* const GetScriptRuns() const;
+
+ /**
* @copydoc ModelInterface::GetNumberOfGlyphs()
*/
virtual Length GetNumberOfGlyphs() const;
#include <dali-toolkit/internal/text/text-controller.h>
#include <dali-toolkit/internal/text/text-model.h>
#include <dali-toolkit/internal/text/text-view.h>
+#include <dali-toolkit/public-api/styling/style-manager.h>
+#include <dali-toolkit/devel-api/styling/style-manager-devel.h>
namespace Dali
{
mAutoScrollDirectionRTL( false ),
mUnderlineSetByString( false ),
mShadowSetByString( false ),
- mFontStyleSetByString( false )
+ mFontStyleSetByString( false ),
+ mShouldClearFocusOnEscape( true )
{
mModel = Model::New();
// Set the text properties to default
mModel->mVisualModel->SetUnderlineEnabled( false );
mModel->mVisualModel->SetUnderlineHeight( 0.0f );
+
+ Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
+ if( styleManager )
+ {
+ bool temp;
+ Property::Map config = Toolkit::DevelStyleManager::GetConfigurations( styleManager );
+ if( config["clearFocusOnEscape"].Get( temp ) )
+ {
+ mShouldClearFocusOnEscape = temp;
+ }
+ }
}
~Impl()
bool mUnderlineSetByString:1; ///< Set when underline is set by string (legacy) instead of map
bool mShadowSetByString:1; ///< Set when shadow is set by string (legacy) instead of map
bool mFontStyleSetByString:1; ///< Set when font style is set by string (legacy) instead of map
+ bool mShouldClearFocusOnEscape:1; ///< Whether text control should clear key input focus
};
} // namespace Text
bool Controller::IsDefaultFontWeightDefined() const
{
- return mImpl->mFontDefaults->weightDefined;
+ if( NULL != mImpl->mFontDefaults )
+ {
+ return mImpl->mFontDefaults->weightDefined;
+ }
+
+ return false;
}
FontWeight Controller::GetDefaultFontWeight() const
bool Controller::IsDefaultFontWidthDefined() const
{
- return mImpl->mFontDefaults->widthDefined;
+ if( NULL != mImpl->mFontDefaults )
+ {
+ return mImpl->mFontDefaults->widthDefined;
+ }
+
+ return false;
}
FontWidth Controller::GetDefaultFontWidth() const
bool Controller::IsDefaultFontSlantDefined() const
{
- return mImpl->mFontDefaults->slantDefined;
+ if( NULL != mImpl->mFontDefaults )
+ {
+ return mImpl->mFontDefaults->slantDefined;
+ }
+ return false;
}
FontSlant Controller::GetDefaultFontSlant() const
// Do nothing.
return false;
}
- else if( Dali::DALI_KEY_ESCAPE == keyCode )
+ else if( Dali::DALI_KEY_ESCAPE == keyCode || Dali::DALI_KEY_BACK == keyCode )
{
- // Escape key is a special case which causes focus loss
- KeyboardFocusLostEvent();
-
- // Will request for relayout.
- relayoutNeeded = true;
+ // Do nothing
+ return false;
}
else if( ( Dali::DALI_KEY_CURSOR_LEFT == keyCode ) ||
( Dali::DALI_KEY_CURSOR_RIGHT == keyCode ) ||
mImpl->mControlInterface = controlInterface;
}
+bool Controller::ShouldClearFocusOnEscape() const
+{
+ return mImpl->mShouldClearFocusOnEscape;
+}
+
// private : Private contructors & copy operator.
Controller::Controller()
*/
void PasteClipboardItemEvent();
+ /**
+ * @brief Return true when text control should clear key input focus when escape key is pressed.
+ *
+ * @return Whether text control should clear key input focus or not when escape key is pressed.
+ */
+ bool ShouldClearFocusOnEscape() const;
+
protected: // Inherit from Text::Decorator::ControllerInterface.
/**
// INTERNAL INCLUDES
#include <dali-toolkit/internal/text/layouts/layout-alignment.h>
#include <dali-toolkit/internal/text/line-run.h>
+#include <dali-toolkit/internal/text/script-run.h>
#include <dali-toolkit/internal/text/text-definitions.h>
namespace Dali
virtual const LineRun* const GetLines() const = 0;
/**
+ * @brief Retrieves the number of script runs.
+ *
+ * @return The number of script runs.
+ */
+ virtual Length GetNumberOfScripts() const = 0;
+
+ /**
+ * @brief Retrieves the script runs.
+ *
+ * @return A pointer to the vector with the runs of characters with the same script..
+ */
+ virtual const ScriptRun* const GetScriptRuns() const = 0;
+
+ /**
* @brief Retrieves the number of laid-out glyphs.
*
* @return The number of laid-out glyphs.
return mVisualModel->mLines.Begin();
}
+Length Model::GetNumberOfScripts() const
+{
+ return mLogicalModel->mScriptRuns.Count();
+}
+
+const ScriptRun* const Model::GetScriptRuns() const
+{
+ return mLogicalModel->mScriptRuns.Begin();
+}
+
Length Model::GetNumberOfGlyphs() const
{
return mVisualModel->mGlyphs.Count();
virtual const LineRun* const GetLines() const;
/**
+ * @copydoc ModelInterface::GetNumberOfScripts()
+ */
+ virtual Length GetNumberOfScripts() const;
+
+ /**
+ * @copydoc ModelInterface::GetScriptRuns()
+ */
+ virtual const ScriptRun* const GetScriptRuns() const;
+
+ /**
* @copydoc ModelInterface::GetNumberOfGlyphs()
*/
virtual Length GetNumberOfGlyphs() const;
case Toolkit::ImageVisual::Property::WRAP_MODE_U:
{
int wrapMode;
- Scripting::GetEnumerationProperty( value, WRAP_MODE_TABLE, WRAP_MODE_TABLE_COUNT, wrapMode );
- mWrapModeU = Dali::WrapMode::Type( wrapMode );
- break;
+ if(Scripting::GetEnumerationProperty( value, WRAP_MODE_TABLE, WRAP_MODE_TABLE_COUNT, wrapMode ))
+ {
+ mWrapModeU = Dali::WrapMode::Type(wrapMode);
+ }
+ else
+ {
+ mWrapModeU = Dali::WrapMode::Type::DEFAULT;
+ }
}
case Toolkit::ImageVisual::Property::WRAP_MODE_V:
{
int wrapMode;
- Scripting::GetEnumerationProperty( value, WRAP_MODE_TABLE, WRAP_MODE_TABLE_COUNT, wrapMode );
- mWrapModeV = Dali::WrapMode::Type( wrapMode );
+ if(Scripting::GetEnumerationProperty( value, WRAP_MODE_TABLE, WRAP_MODE_TABLE_COUNT, wrapMode ))
+ {
+ mWrapModeV = Dali::WrapMode::Type(wrapMode);
+ }
+ else
+ {
+ mWrapModeV = Dali::WrapMode::Type::DEFAULT;
+ }
break;
}
// EXTERNAL INCLUDES
#include <dali/public-api/animation/constraints.h>
+#include <dali/devel-api/text-abstraction/text-abstraction-definitions.h>
// INTERNAL HEADER
#include <dali-toolkit/devel-api/visuals/text-visual-properties.h>
#include <dali-toolkit/internal/visuals/visual-string-constants.h>
#include <dali-toolkit/internal/text/text-font-style.h>
#include <dali-toolkit/internal/text/text-effects-style.h>
+#include <dali-toolkit/internal/text/script-run.h>
namespace Dali
{
}\n
);
-const char* FRAGMENT_SHADER_ATLAS_CLAMP = DALI_COMPOSE_SHADER(
+const char* FRAGMENT_SHADER_ATLAS_CLAMP_RGBA = DALI_COMPOSE_SHADER(
varying mediump vec2 vTexCoord;\n
uniform sampler2D sTexture;\n
uniform sampler2D sStyle;\n
}\n
);
+const char* FRAGMENT_SHADER_ATLAS_CLAMP_L8 = DALI_COMPOSE_SHADER(
+ varying mediump vec2 vTexCoord;\n
+ uniform sampler2D sTexture;\n
+ uniform lowp vec4 uTextColorAnimatable;\n
+ uniform mediump vec4 uAtlasRect;\n
+ uniform lowp vec4 uColor;\n
+ uniform lowp vec3 mixColor;\n
+ uniform lowp float opacity;\n
+ \n
+ void main()\n
+ {\n
+ mediump vec2 texCoord = clamp( mix( uAtlasRect.xy, uAtlasRect.zw, vTexCoord ), uAtlasRect.xy, uAtlasRect.zw );\n
+ mediump float textTexture = texture2D( sTexture, texCoord ).r;\n
+
+ // Set the color of the text to what it is animated to.
+ gl_FragColor = uTextColorAnimatable * textTexture * uColor * vec4( mixColor, opacity );\n
+ }\n
+);
+
/**
* Return Property index for the given string key
* param[in] stringKey the string index key
mControl = actor;
Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY );
-
- Shader shader = mFactoryCache.GetShader( VisualFactoryCache::TEXT_SHADER );
- if( ! shader )
- {
- shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_ATLAS_CLAMP );
- shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
-
- mFactoryCache.SaveShader( VisualFactoryCache::TEXT_SHADER, shader );
- }
+ Shader shader = GetTextShader(mFactoryCache, true);
mImpl->mRenderer = Renderer::New( geometry, shader );
mImpl->mRenderer.SetProperty( Dali::Renderer::Property::DEPTH_INDEX, Toolkit::DepthIndex::CONTENT );
if( ( relayoutSize.width > Math::MACHINE_EPSILON_1000 ) &&
( relayoutSize.height > Math::MACHINE_EPSILON_1000 ) )
{
- Vector4 atlasRect = FULL_TEXTURE_RECT;
+ // Check whether it is a markup text with multiple text colors
+ const Vector4* const colorsBuffer = mController->GetTextModel()->GetColors();
+ bool hasMultipleTextColors = ( NULL != colorsBuffer );
+
+ // Check whether the text contains any emoji
+ bool containsEmoji = false;
- // Create a texture for the text without any styles
- PixelData data = mTypesetter->Render( relayoutSize, Text::Typesetter::RENDER_NO_STYLES );
+ Text::ScriptRunIndex numberOfScripts = mController->GetTextModel()->GetNumberOfScripts();
+ const Text::ScriptRun* scripts = mController->GetTextModel()->GetScriptRuns();
+ for ( Text::ScriptRunIndex scriptIndex = 0u; scriptIndex < numberOfScripts; scriptIndex++ )
+ {
+ const Text::ScriptRun& scriptRun = *( scripts + scriptIndex );
+ if( TextAbstraction::EMOJI == scriptRun.script )
+ {
+ containsEmoji = true;
+ break;
+ }
+ }
+
+ // Check whether the text contains any style colors (e.g. underline color, shadow color, etc.)
+ bool shadowEnabled = false;
+ const Vector2& shadowOffset = mController->GetTextModel()->GetShadowOffset();
+ if ( fabsf( shadowOffset.x ) > Math::MACHINE_EPSILON_1 || fabsf( shadowOffset.y ) > Math::MACHINE_EPSILON_1 )
+ {
+ shadowEnabled = true;
+ }
+
+ const bool underlineEnabled = mController->GetTextModel()->IsUnderlineEnabled();
+
+ if ( hasMultipleTextColors || containsEmoji || shadowEnabled || underlineEnabled )
+ {
+ // Create RGBA textures if the text contains emojis or styles or multiple text colors
- // It may happen the image atlas can't handle a pixel data it exceeds the maximum size.
- // In that case, create a texture. TODO: should tile the text.
+ // Create a texture for the text without any styles
+ PixelData data = mTypesetter->Render( relayoutSize, Text::Typesetter::RENDER_NO_STYLES );
- Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D,
- data.GetPixelFormat(),
- data.GetWidth(),
- data.GetHeight() );
+ // It may happen the image atlas can't handle a pixel data it exceeds the maximum size.
+ // In that case, create a texture. TODO: should tile the text.
- texture.Upload( data );
+ Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D,
+ data.GetPixelFormat(),
+ data.GetWidth(),
+ data.GetHeight() );
- TextureSet textureSet = TextureSet::New();
- textureSet.SetTexture( 0u, texture );
+ texture.Upload( data );
- // Create a texture for all the text styles (without the text itself)
- PixelData styleData = mTypesetter->Render( relayoutSize, Text::Typesetter::RENDER_NO_TEXT );
+ TextureSet textureSet = TextureSet::New();
+ textureSet.SetTexture( 0u, texture );
- Texture styleTexture = Texture::New( Dali::TextureType::TEXTURE_2D,
- styleData.GetPixelFormat(),
- styleData.GetWidth(),
- styleData.GetHeight() );
+ // Create a texture for all the text styles (without the text itself)
+ PixelData styleData = mTypesetter->Render( relayoutSize, Text::Typesetter::RENDER_NO_TEXT );
- styleTexture.Upload( styleData );
+ Texture styleTexture = Texture::New( Dali::TextureType::TEXTURE_2D,
+ styleData.GetPixelFormat(),
+ styleData.GetWidth(),
+ styleData.GetHeight() );
- textureSet.SetTexture( 1u, styleTexture );
+ styleTexture.Upload( styleData );
- // Create a texture as a mask to avoid color glyphs (e.g. emojis) to be affected by text color animation
- PixelData maskData = mTypesetter->Render( relayoutSize, Text::Typesetter::RENDER_MASK );
+ textureSet.SetTexture( 1u, styleTexture );
- Texture maskTexture = Texture::New( Dali::TextureType::TEXTURE_2D,
- styleData.GetPixelFormat(),
- styleData.GetWidth(),
- styleData.GetHeight() );
+ // Create a texture as a mask to avoid color glyphs (e.g. emojis) to be affected by text color animation
+ PixelData maskData = mTypesetter->Render( relayoutSize, Text::Typesetter::RENDER_MASK );
- maskTexture.Upload( maskData );
+ Texture maskTexture = Texture::New( Dali::TextureType::TEXTURE_2D,
+ styleData.GetPixelFormat(),
+ styleData.GetWidth(),
+ styleData.GetHeight() );
- textureSet.SetTexture( 2u, maskTexture );
+ maskTexture.Upload( maskData );
- // Filter mode needs to be set to linear to produce better quality while scaling.
- Sampler sampler = Sampler::New();
- sampler.SetFilterMode( FilterMode::LINEAR, FilterMode::LINEAR );
- textureSet.SetSampler( 0u, sampler );
- textureSet.SetSampler( 1u, sampler );
- textureSet.SetSampler( 2u, sampler );
+ textureSet.SetTexture( 2u, maskTexture );
- mImpl->mRenderer.SetTextures( textureSet );
+ // Filter mode needs to be set to nearest to produce better quality while static.
+ Sampler sampler = Sampler::New();
+ sampler.SetFilterMode( FilterMode::LINEAR, FilterMode::LINEAR );
+ textureSet.SetSampler( 0u, sampler );
+ textureSet.SetSampler( 1u, sampler );
+ textureSet.SetSampler( 2u, sampler );
+
+ mImpl->mRenderer.SetTextures( textureSet );
+
+ Shader shader = GetTextShader(mFactoryCache, true); // RGBA shader
+ mImpl->mRenderer.SetShader(shader);
+ }
+ else
+ {
+ // Create L8 texture if the text contains only single text color with no emoji and no style
+
+ // Create a texture for the text without any styles
+ PixelData data = mTypesetter->Render( relayoutSize, Text::Typesetter::RENDER_NO_STYLES, false, Pixel::L8 );
+
+ // It may happen the image atlas can't handle a pixel data it exceeds the maximum size.
+ // In that case, create a texture. TODO: should tile the text.
+
+ Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D,
+ data.GetPixelFormat(),
+ data.GetWidth(),
+ data.GetHeight() );
+
+ texture.Upload( data );
+
+ TextureSet textureSet = TextureSet::New();
+ textureSet.SetTexture( 0u, texture );
+
+ // Filter mode needs to be set to nearest to produce better quality while static.
+ Sampler sampler = Sampler::New();
+ sampler.SetFilterMode( FilterMode::NEAREST, FilterMode::NEAREST );
+ textureSet.SetSampler( 0u, sampler );
+
+ mImpl->mRenderer.SetTextures( textureSet );
+
+ Shader shader = GetTextShader(mFactoryCache, false); // L8 shader
+ mImpl->mRenderer.SetShader(shader);
+ }
mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED;
+ Vector4 atlasRect = FULL_TEXTURE_RECT;
mImpl->mRenderer.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, atlasRect );
-
- // Check whether it is a markup text with multiple text colors
- const Vector4* const colorsBuffer = mController->GetTextModel()->GetColors();
- bool hasMultipleTextColors = ( NULL != colorsBuffer );
mImpl->mRenderer.RegisterProperty( "uHasMultipleTextColors", static_cast<float>( hasMultipleTextColors ) );
+ mImpl->mRenderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON);
+
//Register transform properties
mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT );
}
}
+Shader TextVisual::GetTextShader( VisualFactoryCache& factoryCache, bool isRgbaTexture )
+{
+ Shader shader;
+ if( isRgbaTexture )
+ {
+ shader = factoryCache.GetShader( VisualFactoryCache::TEXT_SHADER_RGBA );
+ if( !shader )
+ {
+ shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_ATLAS_CLAMP_RGBA );
+ shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
+ factoryCache.SaveShader( VisualFactoryCache::TEXT_SHADER_RGBA, shader );
+ }
+ }
+ else
+ {
+ shader = factoryCache.GetShader( VisualFactoryCache::TEXT_SHADER_L8 );
+ if( !shader )
+ {
+ shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_ATLAS_CLAMP_L8 );
+ shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
+ factoryCache.SaveShader( VisualFactoryCache::TEXT_SHADER_L8, shader );
+ }
+ }
+
+ return shader;
+}
+
} // namespace Internal
} // namespace Toolkit
void RemoveTextureSet();
/**
+ * Get the text rendering shader.
+ * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+ * @param[in] isRgbaTexture Whether the texture is in RGBA format.
+ */
+ Shader GetTextShader( VisualFactoryCache& factoryCache, bool isRgbaTexture );
+
+ /**
* @brief Retrieve the text's controller.
* @param[in] visual The text visual.
* @return The text controller
#include "texture-manager.h"
// EXTERNAL HEADERS
+#include <cstdlib>
+#include <dali/devel-api/adaptor-framework/environment-variable.h>
#include <dali/devel-api/common/hash.h>
#include <dali/devel-api/images/texture-set-image.h>
#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
#include <dali/integration-api/debug.h>
// INTERNAL HEADERS
-#include <dali/integration-api/debug.h>
-#include <dali-toolkit/devel-api/image-loader/async-image-loader-devel.h>
#include <dali-toolkit/internal/image-loader/image-atlas-impl.h>
-#include <dali-toolkit/internal/image-loader/async-image-loader-impl.h>
#include <dali-toolkit/public-api/image-loader/sync-image-loader.h>
+namespace
+{
+
+constexpr auto DEFAULT_NUMBER_OF_LOCAL_LOADER_THREADS = size_t{4u};
+constexpr auto DEFAULT_NUMBER_OF_REMOTE_LOADER_THREADS = size_t{8u};
+
+constexpr auto NUMBER_OF_LOCAL_LOADER_THREADS_ENV = "DALI_TEXTURE_LOCAL_THREADS";
+constexpr auto NUMBER_OF_REMOTE_LOADER_THREADS_ENV = "DALI_TEXTURE_REMOTE_THREADS";
+
+size_t GetNumberOfThreads(const char* environmentVariable, size_t defaultValue)
+{
+ using Dali::EnvironmentVariable::GetEnvironmentVariable;
+ auto numberString = GetEnvironmentVariable(environmentVariable);
+ auto numberOfThreads = numberString ? std::strtol(numberString, nullptr, 10) : 0;
+ return (numberOfThreads > 0) ? numberOfThreads : defaultValue;
+}
+
+size_t GetNumberOfLocalLoaderThreads()
+{
+ return GetNumberOfThreads(NUMBER_OF_LOCAL_LOADER_THREADS_ENV, DEFAULT_NUMBER_OF_LOCAL_LOADER_THREADS);
+}
+
+size_t GetNumberOfRemoteLoaderThreads()
+{
+ return GetNumberOfThreads(NUMBER_OF_REMOTE_LOADER_THREADS_ENV, DEFAULT_NUMBER_OF_REMOTE_LOADER_THREADS);
+}
+
+} // namespace
namespace Dali
{
TextureManager::TextureManager()
-: mAsyncLocalLoader( Toolkit::AsyncImageLoader::New() ),
- mAsyncRemoteLoader( Toolkit::AsyncImageLoader::New() ),
- mCurrentTextureId( 0 )
+: mCurrentTextureId( 0 ),
+ mAsyncLocalLoaders( GetNumberOfLocalLoaderThreads(), [&]() { return AsyncLoadingHelper(*this); } ),
+ mAsyncRemoteLoaders( GetNumberOfRemoteLoaderThreads(), [&]() { return AsyncLoadingHelper(*this); } )
{
- DevelAsyncImageLoader::PixelBufferLoadedSignal(mAsyncLocalLoader).Connect( this, &TextureManager::AsyncLocalLoadComplete );
- DevelAsyncImageLoader::PixelBufferLoadedSignal(mAsyncRemoteLoader).Connect( this, &TextureManager::AsyncRemoteLoadComplete );
}
TextureManager::TextureId TextureManager::RequestLoad(
if( !textureInfo.loadSynchronously )
{
- if( textureInfo.url.IsLocal() )
- {
- mAsyncLocalLoadingInfoContainer.push_back( AsyncLoadingInfo( textureInfo.textureId ) );
- mAsyncLocalLoadingInfoContainer.back().loadId =
- GetImplementation(mAsyncLocalLoader).Load( textureInfo.url, textureInfo.desiredSize,
- textureInfo.fittingMode,
- textureInfo.samplingMode, true );
- }
- else
- {
- mAsyncRemoteLoadingInfoContainer.push_back( AsyncLoadingInfo( textureInfo.textureId ) );
- mAsyncRemoteLoadingInfoContainer.back().loadId =
- GetImplementation(mAsyncRemoteLoader).Load( textureInfo.url, textureInfo.desiredSize,
- textureInfo.fittingMode,
- textureInfo.samplingMode, true );
- }
+ auto& loadersContainer = textureInfo.url.IsLocal() ? mAsyncLocalLoaders : mAsyncRemoteLoaders;
+ auto loadingHelperIt = loadersContainer.GetNext();
+ DALI_ASSERT_ALWAYS(loadingHelperIt != loadersContainer.End());
+ loadingHelperIt->Load(textureInfo.textureId, textureInfo.url,
+ textureInfo.desiredSize, textureInfo.fittingMode,
+ textureInfo.samplingMode, true);
}
}
}
}
-void TextureManager::AsyncLocalLoadComplete( uint32_t id, Devel::PixelBuffer pixelBuffer )
-{
- AsyncLoadComplete( mAsyncLocalLoadingInfoContainer, id, pixelBuffer );
-}
-
-void TextureManager::AsyncRemoteLoadComplete( uint32_t id, Devel::PixelBuffer pixelBuffer )
-{
- AsyncLoadComplete( mAsyncRemoteLoadingInfoContainer, id, pixelBuffer );
-}
-
void TextureManager::AsyncLoadComplete( AsyncLoadingInfoContainerType& loadingContainer, uint32_t id, Devel::PixelBuffer pixelBuffer )
{
DALI_LOG_INFO( gTextureManagerLogFilter, Debug::Concise, "TextureManager::AsyncLoadComplete( id:%d )\n", id );
TextureManager::~TextureManager()
{
- mTextureInfoContainer.clear();
- mAsyncLocalLoadingInfoContainer.clear();
- mAsyncRemoteLoadingInfoContainer.clear();
}
+TextureManager::AsyncLoadingHelper::AsyncLoadingHelper(TextureManager& textureManager)
+: AsyncLoadingHelper(Toolkit::AsyncImageLoader::New(), textureManager,
+ AsyncLoadingInfoContainerType())
+{
+}
+void TextureManager::AsyncLoadingHelper::Load(TextureId textureId,
+ const VisualUrl& url,
+ ImageDimensions desiredSize,
+ FittingMode::Type fittingMode,
+ SamplingMode::Type samplingMode,
+ bool orientationCorrection)
+{
+ mLoadingInfoContainer.push_back(AsyncLoadingInfo(textureId));
+ auto id = mLoader.Load(url.GetUrl(), desiredSize, fittingMode, samplingMode, orientationCorrection);
+ mLoadingInfoContainer.back().loadId = id;
+}
+TextureManager::AsyncLoadingHelper::AsyncLoadingHelper(AsyncLoadingHelper&& rhs)
+: AsyncLoadingHelper(rhs.mLoader, rhs.mTextureManager, std::move(rhs.mLoadingInfoContainer))
+{
+}
+
+TextureManager::AsyncLoadingHelper::AsyncLoadingHelper(
+ Toolkit::AsyncImageLoader loader,
+ TextureManager& textureManager,
+ AsyncLoadingInfoContainerType&& loadingInfoContainer)
+: mLoader(loader),
+ mTextureManager(textureManager),
+ mLoadingInfoContainer(std::move(loadingInfoContainer))
+{
+ DevelAsyncImageLoader::PixelBufferLoadedSignal(mLoader).Connect(
+ this, &AsyncLoadingHelper::AsyncLoadComplete);
+}
+
+void TextureManager::AsyncLoadingHelper::AsyncLoadComplete(uint32_t id,
+ Devel::PixelBuffer pixelBuffer)
+{
+ mTextureManager.AsyncLoadComplete(mLoadingInfoContainer, id, pixelBuffer);
+}
} // namespace Internal
*/
// EXTERNAL INCLUDES
+#include <deque>
+#include <functional>
#include <string>
#include <dali/public-api/common/dali-vector.h>
#include <dali/public-api/object/ref-object.h>
#include <dali/public-api/rendering/texture-set.h>
#include <dali/devel-api/common/owner-container.h>
#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
-#include <deque>
// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/image-loader/async-image-loader-devel.h>
#include <dali-toolkit/devel-api/image-loader/image-atlas.h>
#include <dali-toolkit/public-api/image-loader/async-image-loader.h>
#include <dali-toolkit/internal/visuals/texture-upload-observer.h>
#include <dali-toolkit/internal/visuals/visual-url.h>
+#include <dali-toolkit/internal/helpers/round-robin-container-view.h>
+#include <dali-toolkit/internal/image-loader/async-image-loader-impl.h>
namespace Dali
const bool useAtlas,
TextureId maskTextureId );
+private:
+
+ /**
+ * @brief Helper class to keep the relation between AsyncImageLoader and corresponding LoadingInfo container
+ */
+ class AsyncLoadingHelper : public ConnectionTracker
+ {
+ public:
+ /**
+ * @brief Create an AsyncLoadingHelper.
+ * @param[in] textureManager Reference to the texture manager
+ */
+ AsyncLoadingHelper(TextureManager& textureManager);
+
+ /**
+ * @brief Load a new texture.
+ * @param[in] textureId TextureId to reference the texture that will be loaded
+ * @param[in] url The URL of the image to load
+ * @param[in] desiredSize The size the image is likely to appear at. This can be set to 0,0 for automatic
+ * @param[in] fittingMode The FittingMode to use
+ * @param[in] samplingMode The SamplingMode to use
+ * @param[in] orientationCorrection Whether to use image metadata to rotate or flip the image, e.g., from portrait to landscape
+ */
+ void Load(TextureId textureId,
+ const VisualUrl& url,
+ ImageDimensions desiredSize,
+ FittingMode::Type fittingMode,
+ SamplingMode::Type samplingMode,
+ bool orientationCorrection);
+
+ public:
+ AsyncLoadingHelper(const AsyncLoadingHelper&) = delete;
+ AsyncLoadingHelper& operator=(const AsyncLoadingHelper&) = delete;
+
+ AsyncLoadingHelper(AsyncLoadingHelper&& rhs);
+ AsyncLoadingHelper& operator=(AsyncLoadingHelper&&rhs) = delete;
+
+ private:
+ /**
+ * @brief Main constructor that used by all other constructors
+ */
+ AsyncLoadingHelper(Toolkit::AsyncImageLoader loader,
+ TextureManager& textureManager,
+ AsyncLoadingInfoContainerType&& loadingInfoContainer);
+
+ /**
+ * @brief Callback to be called when texture loading is complete, it passes the pixel buffer on to texture manager.
+ * @param[in] id Loader id
+ * @param[in] pixelBuffer Image data
+ */
+ void AsyncLoadComplete(uint32_t id, Devel::PixelBuffer pixelBuffer);
+
+ private:
+ Toolkit::AsyncImageLoader mLoader;
+ TextureManager& mTextureManager;
+ AsyncLoadingInfoContainerType mLoadingInfoContainer;
+ };
private:
/**
- * Undefined copy constructor.
+ * Deleted copy constructor.
*/
- TextureManager( const TextureManager& );
+ TextureManager( const TextureManager& ) = delete;
/**
- * Undefined assignment operator.
+ * Deleted assignment operator.
*/
- TextureManager& operator=( const TextureManager& rhs );
+ TextureManager& operator=( const TextureManager& rhs ) = delete;
/**
* This is called by the TextureManagerUploadObserver when an observer is destroyed.
private: // Member Variables:
- AsyncLoadingInfoContainerType mAsyncLocalLoadingInfoContainer; ///< Used to manage Asynchronous loads in progress
- AsyncLoadingInfoContainerType mAsyncRemoteLoadingInfoContainer; ///< Used to manage Asynchronous loads in progress
- AtlasInfoContainerType mAtlasContainer; ///< Used to manage Atlas creation and destruction
- TextureInfoContainerType mTextureInfoContainer; ///< Used to manage the life-cycle and caching of Textures
- Toolkit::AsyncImageLoader mAsyncLocalLoader; ///< The Asynchronous image loader used to provide all local async loads
- Toolkit::AsyncImageLoader mAsyncRemoteLoader; ///< The Asynchronous image loader used to provide all remote async loads
- TextureId mCurrentTextureId; ///< The current value used for the unique Texture Id generation
+ AtlasInfoContainerType mAtlasContainer; ///< Used to manage Atlas creation and destruction
+ TextureInfoContainerType mTextureInfoContainer; ///< Used to manage the life-cycle and caching of Textures
+ TextureId mCurrentTextureId; ///< The current value used for the unique Texture Id generation
+ RoundRobinContainerView<AsyncLoadingHelper> mAsyncLocalLoaders; ///< The Asynchronous image loaders used to provide all local async loads
+ RoundRobinContainerView<AsyncLoadingHelper> mAsyncRemoteLoaders; ///< The Asynchronous image loaders used to provide all remote async loads
};
IMAGE_SHADER_ATLAS_CUSTOM_WRAP,
NINE_PATCH_SHADER,
SVG_SHADER,
- TEXT_SHADER,
+ TEXT_SHADER_RGBA,
+ TEXT_SHADER_L8,
WIREFRAME_SHADER,
SHADER_TYPE_MAX = WIREFRAME_SHADER
};
const unsigned int TOOLKIT_MAJOR_VERSION = 1;
const unsigned int TOOLKIT_MINOR_VERSION = 2;
-const unsigned int TOOLKIT_MICRO_VERSION = 55;
+const unsigned int TOOLKIT_MICRO_VERSION = 56;
const char * const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
* @brief The URL of the image.
* @details Name "url", type Property::STRING or Property::ARRAY of Property::STRING
* @note The array form is used for generating animated image visuals.
+ * @note The number of threads used for local and remote image loading can be controlled by the
+ * environment variables DALI_TEXTURE_LOCAL_THREADS and DALI_TEXTURE_REMOTE_THREADS respectively.
+ * The default values are 4 threads for local image loading and 8 threads for remote image loading.
* @SINCE_1_1.45
* @note Mandatory.
*/
{
"config":
{
- "alwaysShowFocus":false
+ "alwaysShowFocus":false,
+ "clearFocusOnEscape":false
},
"styles":
{
{
"config":
{
- "alwaysShowFocus":false
+ "alwaysShowFocus":false,
+ "clearFocusOnEscape":true
},
"styles":
{
{
"config":
{
- "alwaysShowFocus":false
+ "alwaysShowFocus":false,
+ "clearFocusOnEscape":true
},
"styles":
{
Name: dali-toolkit
-Summary: The OpenGLES Canvas Core Library Toolkit
-Version: 1.2.55
+Summary: Dali 3D engine Toolkit
+Version: 1.2.56
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-3-Clause and MIT
Requires(post): /sbin/ldconfig
Requires(postun): /sbin/ldconfig
+%if 0%{?tizen_version_major} < 4
+%define disable_cxx03_build 1
+%endif
+
BuildRequires: pkgconfig
BuildRequires: pkgconfig(dlog)
BuildRequires: pkgconfig(dali-core)
+%if !0%{?disable_cxx03_build}
+BuildRequires: pkgconfig(dali-core-cxx03)
+%endif
BuildRequires: gettext
# dali-toolkit only need to know the interfaces(APIs) of dali-adaptor(the devel package).
# It doesn't need to know which adaptor will be used by applications.
# Applications or dali-addon will decide which one they will use.
BuildRequires: dali-adaptor-devel
+%if !0%{?disable_cxx03_build}
+BuildRequires: dali-adaptor-devel-cxx03
+%endif
#need libtzplatform-config for directory if tizen version is 3.x
%endif
%description
-The OpenGLES Canvas Core Library Toolkit - a set of controls that provide
+Dali 3D engine Toolkit - a set of controls that provide
user interface functionality.
##############################
dali-toolkit default resource files for 1920x1080
Contain po / sounds / common images / style / style images
+%if !0%{?disable_cxx03_build}
+%package cxx03
+Summary: Dali 3D engine Toolkit with cxx03
+Provides: %{name}-cxx03 = %{version}-%{release}
+
+%description cxx03
+Dali 3D engine Toolkit with cxx03
+%endif
+
##############################
# devel
##############################
%package devel
-Summary: Application development package for the OpenGLES Canvas toolkit
+Summary: Application development package for Dali 3D engine toolkit
Group: Development/Building
Requires: %{name} = %{version}-%{release}
%description devel
-Application development package for the OpenGLES Canvas toolkit - headers and package config
+Application development package for Dali 3D engine toolkit - headers and package config
##############################
# Preparation
%if 0%{?enable_debug}
--enable-debug \
%endif
- --enable-i18n=yes
+ --enable-i18n=yes \
+ --enable-rename-so=no
make %{?jobs:-j%jobs}
+pushd %{_builddir}/%{name}-%{version}/build/tizen
+%make_install DALI_DATA_RW_DIR="%{dali_data_rw_dir}" DALI_DATA_RO_DIR="%{dali_data_ro_dir}"
+popd
+
+pushd %{buildroot}%{_libdir}
+for FILE in libdali-toolkit-cxx11.so*; do mv "$FILE" "%{_builddir}/%{name}-%{version}/build/tizen/$FILE"; done
+mv pkgconfig/dali-toolkit.pc %{_builddir}/%{name}-%{version}/build/tizen/dali-toolkit.pc
+popd
+
+%if !0%{?disable_cxx03_build}
+make clean
+
+libtoolize --force
+cd %{_builddir}/dali-toolkit-%{version}/build/tizen
+autoreconf --install
+
+DALI_DATA_RW_DIR="%{dali_data_rw_dir}" ; export DALI_DATA_RW_DIR
+DALI_DATA_RO_DIR="%{dali_data_ro_dir}" ; export DALI_DATA_RO_DIR
+
+%configure --enable-profile=TIZEN \
+ --enable-cxx03-abi=yes \
+%if 0%{?enable_debug}
+ --enable-debug \
+%endif
+ --enable-i18n=yes \
+ --enable-rename-so=no
+
+make %{?jobs:-j%jobs}
+%endif
+
##############################
# Installation
##############################
%install
rm -rf %{buildroot}
-pushd build/tizen
+pushd %{_builddir}/%{name}-%{version}/build/tizen
%make_install DALI_DATA_RW_DIR="%{dali_data_rw_dir}" DALI_DATA_RO_DIR="%{dali_data_ro_dir}"
+for FILE in libdali-toolkit-cxx11.so*; do mv "$FILE" "%{buildroot}%{_libdir}/$FILE"; done
+mv dali-toolkit.pc %{buildroot}%{_libdir}/pkgconfig/dali-toolkit.pc
+
# PO
{
cd %{_builddir}/dali-toolkit-%{version}/dali-toolkit/po
} &> /dev/null
popd
+#############################
+#rename
+#############################
+pushd %{buildroot}%{_libdir}
+rm -rf libdali-toolkit.so
+rm -rf libdali-toolkit-cxx11.so
+%if !0%{?disable_cxx03_build}
+ln -s libdali-toolkit.so.0.0.* libdali-toolkit-cxx03.so
+%endif
+ln -s libdali-toolkit-cxx11.so.0.0.* libdali-toolkit.so
+popd
+
# Remove default style and style images which are for Linux build
rm -rf %{buildroot}%{dali_toolkit_style_files}/*
%manifest dali-toolkit.manifest
%endif
%defattr(-,root,root,-)
-%{_libdir}/lib%{name}.so*
+%{_libdir}/libdali-toolkit-cxx11.so.*
+%{_libdir}/libdali-toolkit.so
+%license LICENSE
+
+%if !0%{?disable_cxx03_build}
+%files cxx03
+%if 0%{?enable_dali_smack_rules}
+%manifest dali-toolkit.manifest-smack
+%else
+%manifest dali-toolkit.manifest
+%endif
+%defattr(-,root,root,-)
+%{_libdir}/libdali-toolkit.so.*
+%{_libdir}/libdali-toolkit-cxx03.so
%license LICENSE
+%endif
%files devel
%defattr(-,root,root,-)
-%{dev_include_path}/%{name}/*
-%{_libdir}/pkgconfig/*.pc
+%{dev_include_path}/dali-toolkit/*
+%{_libdir}/pkgconfig/dali-toolkit.pc
%files resources_480x800
%manifest dali-toolkit-resources.manifest