/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 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.
*/
#include <iostream>
-#include <stdlib.h>
+#include <iterator>
+#include <vector>
+#include <algorithm>
+#include <cstdlib>
+
#include <dali-toolkit-test-suite-utils.h>
#include <dali-toolkit/devel-api/builder/builder.h>
+#include <dali-toolkit/devel-api/builder/base64-encoding.h>
#include <dali/integration-api/events/touch-event-integ.h>
#include <dali-toolkit/dali-toolkit.h>
#include <test-button.h>
#include <test-animation-data.h>
+
#define STRINGIFY(A)#A
using namespace Dali;
END_TEST;
}
+
+
+int UtcDaliBase64EncodingP(void)
+{
+ std::vector<uint32_t> data = { 0, 1, 2, 3, 4, 5, std::numeric_limits<uint32_t>::min(), std::numeric_limits<uint32_t>::max() };
+
+ Property::Value value;
+ EncodeBase64PropertyData( value, data );
+
+ std::cout << "Max uint32_t:" << std::numeric_limits<uint32_t>::max() << std::endl;
+ std::cout << "Input data: ";
+ std::ostream_iterator<uint32_t> out_it (std::cout,", ");
+ std::copy ( data.begin(), data.end(), out_it );
+ std::cout << std::endl;
+
+ std::string output;
+ DALI_TEST_CHECK( value.Get( output ) );
+ DALI_TEST_EQUALS( output, "AAAAAAEAAAACAAAAAwAAAAQAAAAFAAAAAAAAAP////8", TEST_LOCATION );
+
+ std::cout << "Output data: " << output << std::endl;
+
+ END_TEST;
+}
+
+int UtcDaliBase64EncodingN(void)
+{
+ tet_infoline( "Test encoding an empty vector returns empty string" );
+ std::vector<uint32_t> data;
+
+ Property::Value value;
+ EncodeBase64PropertyData( value, data );
+
+ std::string output;
+ DALI_TEST_CHECK( value.Get( output ) );
+ DALI_TEST_EQUALS( output.empty(), true, TEST_LOCATION );
+
+ END_TEST;
+}
+
+template <typename T>
+int b64l(std::vector<T>&data)
+{
+ auto lengthInBytes = 4*data.size();
+ return ceil( lengthInBytes * 1.33333f );
+}
+
+int UtcDaliBase64EncodingP02(void)
+{
+ tet_infoline( "Test encoding vectors of lengths m .. m+4 encode and decode back to the same length vectors" );
+
+ std::vector<uint32_t> testData;
+ for(int i=0; i<8; ++i ) // 8 chosen to stay within single string output
+ {
+ testData.push_back(i);
+ }
+ Property::Value value;
+ EncodeBase64PropertyData( value, testData );
+
+ std::string output;
+ DALI_TEST_CHECK( value.Get( output ) );
+ DALI_TEST_EQUALS( output.empty(), false, TEST_LOCATION);
+ DALI_TEST_EQUALS( output.length(), b64l(testData), TEST_LOCATION );
+
+ std::vector<uint32_t> outData;
+ DecodeBase64PropertyData( value, outData );
+ DALI_TEST_EQUALS( testData.size(), outData.size(), TEST_LOCATION );
+ DALI_TEST_EQUALS( std::equal( testData.begin(), testData.end(), outData.begin()), true, TEST_LOCATION );
+
+ // n+1
+ testData.push_back( 12345 );
+ EncodeBase64PropertyData( value, testData );
+
+ DALI_TEST_CHECK( value.Get( output ) );
+ DALI_TEST_EQUALS( output.empty(), false, TEST_LOCATION);
+ DALI_TEST_EQUALS( output.length(), b64l(testData), TEST_LOCATION );
+
+ outData.clear();
+ DecodeBase64PropertyData( value, outData );
+ DALI_TEST_EQUALS( testData.size(), outData.size(), TEST_LOCATION );
+ DALI_TEST_EQUALS( std::equal( testData.begin(), testData.end(), outData.begin()), true, TEST_LOCATION );
+
+ // n+2
+ testData.push_back( 67890 );
+ EncodeBase64PropertyData( value, testData );
+
+ DALI_TEST_CHECK( value.Get( output ) );
+ DALI_TEST_EQUALS( output.empty(), false, TEST_LOCATION);
+ DALI_TEST_EQUALS( output.length(), b64l(testData), TEST_LOCATION );
+
+ outData.clear();
+ DecodeBase64PropertyData( value, outData );
+ DALI_TEST_EQUALS( testData.size(), outData.size(), TEST_LOCATION );
+ DALI_TEST_EQUALS( std::equal( testData.begin(), testData.end(), outData.begin()), true, TEST_LOCATION );
+
+ // n+3
+ testData.push_back( -1 );
+ EncodeBase64PropertyData( value, testData );
+
+ DALI_TEST_CHECK( value.Get( output ) );
+ DALI_TEST_EQUALS( output.empty(), false, TEST_LOCATION);
+ DALI_TEST_EQUALS( output.length(), b64l(testData), TEST_LOCATION );
+
+ outData.clear();
+ DecodeBase64PropertyData( value, outData );
+ DALI_TEST_EQUALS( testData.size(), outData.size(), TEST_LOCATION );
+ DALI_TEST_EQUALS( std::equal( testData.begin(), testData.end(), outData.begin()), true, TEST_LOCATION );
+
+
+ END_TEST;
+}
+
+
+int UtcDaliBase64EncodingP03(void)
+{
+ tet_infoline( "Test encoding a vector of length 12 has output within single string" );
+
+ std::vector<uint32_t> testData;
+ for(int i=0; i<12; ++i )
+ {
+ testData.push_back(i);
+ }
+ Property::Value value;
+ EncodeBase64PropertyData( value, testData );
+
+ std::string output;
+ DALI_TEST_CHECK( value.Get( output ) );
+ DALI_TEST_EQUALS( output.empty(), false, TEST_LOCATION);
+ DALI_TEST_EQUALS( output.length(), b64l(testData), TEST_LOCATION );
+
+ std::vector<uint32_t> outData;
+ DecodeBase64PropertyData( value, outData );
+ DALI_TEST_EQUALS( testData.size(), outData.size(), TEST_LOCATION );
+
+ END_TEST;
+}
+
+
+int UtcDaliBase64EncodingP04(void)
+{
+ tet_infoline( "Test encoding a vector of length 13 has output split over 2 strings" );
+
+ std::vector<uint32_t> testData;
+ for(int i=0; i<13; ++i )
+ {
+ testData.push_back(i);
+ }
+ Property::Value value;
+ EncodeBase64PropertyData( value, testData );
+
+ auto array = value.GetArray();
+ DALI_TEST_CHECK( array );
+
+ DALI_TEST_EQUALS( array->Count(), 2, TEST_LOCATION );
+
+ std::vector<uint32_t> outData;
+ DecodeBase64PropertyData( value, outData );
+ DALI_TEST_EQUALS( testData.size(), outData.size(), TEST_LOCATION );
+
+ END_TEST;
+}
+
+
+int UtcDaliBase64EncodingP05(void)
+{
+ tet_infoline( "Test encoding a vector of length 24 has output split over 2 strings" );
+
+ std::vector<uint32_t> testData;
+ for(int i=0; i<24; ++i )
+ {
+ testData.push_back(i);
+ }
+ Property::Value value;
+ EncodeBase64PropertyData( value, testData );
+
+ auto array = value.GetArray();
+ DALI_TEST_CHECK( array );
+
+ DALI_TEST_EQUALS( array->Count(), 2, TEST_LOCATION );
+
+ std::vector<uint32_t> outData;
+ DecodeBase64PropertyData( value, outData );
+ DALI_TEST_EQUALS( testData.size(), outData.size(), TEST_LOCATION );
+
+ END_TEST;
+}
+
+
+int UtcDaliBase64EncodingP06(void)
+{
+ tet_infoline( "Test encoding a vector of arbitrary length decodes OK." );
+
+ std::vector<uint32_t> testData;
+ for(int i=0; i<97; ++i )
+ {
+ testData.push_back(i);
+ }
+ Property::Value value;
+ EncodeBase64PropertyData( value, testData );
+
+ auto array = value.GetArray();
+ DALI_TEST_CHECK( array );
+
+ std::vector<uint32_t> outData;
+ DecodeBase64PropertyData( value, outData );
+ DALI_TEST_EQUALS( testData.size(), outData.size(), TEST_LOCATION );
+
+ END_TEST;
+}
+
+
+int UtcDaliBase64DecodingN01(void)
+{
+ tet_infoline( "Test decoding empty string results in empty data" );
+
+ Property::Value value("");
+ std::vector<uint32_t> outputData;
+ DecodeBase64PropertyData( value, outputData);
+ DALI_TEST_EQUALS( outputData.size(), 0, TEST_LOCATION );
+ END_TEST;
+}
+
+
+int UtcDaliBase64DecodingN02(void)
+{
+ tet_infoline( "Test decoding array with non-string values results in empty data" );
+
+ Property::Array array;
+ array.Resize(2);
+ array[0] = "Stuff, things";
+ array[1] = 1;
+ Property::Value value(array);
+
+ std::vector<uint32_t> outputData;
+ DecodeBase64PropertyData( value, outputData);
+ DALI_TEST_EQUALS( outputData.size(), 0, TEST_LOCATION );
+ END_TEST;
+}
+
+int UtcDaliBase64DecodingP01(void)
+{
+ tet_infoline( "Test decoding string of known data gives expected result");
+
+ std::string testInput("//////7+/v4DAgEA");
+ std::vector<uint32_t> expectedResults = { 0xffffffff, 0xfefefefe, 0x00010203 };
+
+ std::vector<uint32_t> outputData;
+ DecodeBase64PropertyData(Property::Value(testInput), outputData);
+
+ DALI_TEST_EQUALS( std::equal( expectedResults.begin(), expectedResults.end(), outputData.begin() ), true,
+ TEST_LOCATION );
+
+ END_TEST;
+}
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 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.
END_TEST;
}
+
+int UtcDaliImageViewUsingAtlasAndGetNaturalSize(void)
+{
+ ToolkitTestApplication application;
+
+ // Check ImageView with background and main image, to ensure both visuals are marked as loaded
+ ImageView imageView = ImageView::New();
+ Property::Map imageMap;
+ imageMap[ Toolkit::Visual::Property::TYPE ] = Toolkit::Visual::IMAGE;
+ imageMap[ Toolkit::ImageVisual::Property::URL ] = gImage_34_RGBA;
+ imageMap[ Toolkit::ImageVisual::Property::ATLASING ] = true;
+ imageView.SetProperty( Toolkit::ImageView::Property::IMAGE, imageMap );
+ Stage::GetCurrent().Add( imageView );
+
+ // Trigger a potential relayout
+ application.SendNotification();
+ application.Render();
+
+ Vector3 naturalSize = imageView.GetNaturalSize();
+
+ DALI_TEST_EQUALS( naturalSize.width, 34.0f, TEST_LOCATION );
+ DALI_TEST_EQUALS( naturalSize.height, 34.0f, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliImageViewFillMode(void)
+{
+ ToolkitTestApplication application;
+
+ tet_infoline( "Create an ImageVisual without padding and set the fill-mode to fill" );
+ tet_infoline( " There should be no need to change the transform, our size-policy should be relative and size shoudl be [1,1]");
+
+ ImageView imageView = ImageView::New();
+ Property::Map imageMap;
+ imageMap.Add( Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE );
+ imageMap.Add( Toolkit::ImageVisual::Property::URL, gImage_600_RGB );
+ imageMap.Add( DevelVisual::Property::VISUAL_FITTING_MODE, DevelVisual::FittingMode::FILL );
+
+ imageView.SetProperty( Toolkit::ImageView::Property::IMAGE, imageMap );
+
+ Stage::GetCurrent().Add( imageView );
+
+ // Trigger a potential relayout
+ application.SendNotification();
+ application.Render();
+
+ Toolkit::Visual::Base visual = DevelControl::GetVisual( Toolkit::Internal::GetImplementation( imageView ), Toolkit::ImageView::Property::IMAGE );
+ Property::Map returnedMap;
+ visual.CreatePropertyMap( returnedMap );
+
+ Property::Value* value = returnedMap.Find( Toolkit::Visual::Property::TRANSFORM );
+ DALI_TEST_CHECK( value );
+ Property::Map* map = value->GetMap();
+ DALI_TEST_CHECK( map );
+
+ // If there's
+ value = map->Find( Toolkit::Visual::Transform::Property::SIZE );
+ DALI_TEST_CHECK( value );
+ DALI_TEST_EQUALS( value->Get< Vector2 >(), Vector2::ONE, TEST_LOCATION ); // Relative size so will take up 100%
+
+ value = map->Find( Toolkit::Visual::Transform::Property::SIZE_POLICY );
+ DALI_TEST_CHECK( value );
+ DALI_TEST_CHECK( value->Get< int >() == Toolkit::Visual::Transform::Policy::RELATIVE );
+
+ END_TEST;
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 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 <sstream>
+#include <iterator>
+
+#include <dali/public-api/object/property-value.h>
+#include <dali/public-api/object/property-array.h>
+#include <dali-toolkit/devel-api/builder/base64-encoding.h>
+#include <dali-toolkit/third-party/base-n/basen.hpp>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace
+{
+const int MAX_PROPERTY_STRING_LENGTH(64); // Cuts larger strings into blocks of this size.
+
+bool GetStringFromProperty( const Property::Value& value, std::string& output )
+{
+ bool extracted = false;
+ if( value.Get( output ) )
+ {
+ extracted = true;
+ }
+ else
+ {
+ Property::Array* array = value.GetArray();
+ if( array )
+ {
+ const unsigned int arraySize = array->Size();
+ for( unsigned int i = 0; i < arraySize; ++i )
+ {
+ std::string element;
+ if( array->GetElementAt( i ).Get( element ) )
+ {
+ extracted = true;
+ output += element;
+ }
+ else
+ {
+ // If property in array is anything other than a string, then it is invalid so break and clear output.
+ output.clear();
+ extracted = false;
+ break;
+ }
+ }
+ }
+ }
+ return extracted;
+}
+
+}//anonymous namespace
+
+bool DecodeBase64PropertyData( const Property::Value& value, std::vector<uint32_t>& outputData )
+{
+ bool decoded = false;
+ std::string encodedString;
+
+
+ if( GetStringFromProperty( value, encodedString ) )
+ {
+ std::vector<unsigned char> outputTmpData;
+ outputTmpData.reserve( ceil( encodedString.size() * 0.75f ) );
+ bn::decode_b64( encodedString.begin(), encodedString.end(), std::back_inserter(outputTmpData) );
+
+ outputData.clear();
+ outputData.resize( outputTmpData.size() / sizeof(uint32_t) );
+ // Treat as a block of data
+ memcpy( &outputData[0], &outputTmpData[0], outputTmpData.size() );
+
+ decoded = true;
+ }
+ return decoded;
+}
+
+void EncodeBase64PropertyData( Property::Value& value, const std::vector<uint32_t>& inputData )
+{
+ std::ostringstream oss;
+
+ bn::encode_b64( reinterpret_cast<const char*>(&inputData[0]),
+ reinterpret_cast<const char*>(&inputData[0]+inputData.size()),
+ std::ostream_iterator<unsigned char>(oss, "") );
+
+
+ std::string encodedString = oss.str();
+ if( encodedString.length() > MAX_PROPERTY_STRING_LENGTH)
+ {
+ // cut string up into blocks of MAX_PROPERTY_STRING_LENGTH and store to an array
+ auto numStrings = encodedString.length() / MAX_PROPERTY_STRING_LENGTH +
+ ((encodedString.length() % MAX_PROPERTY_STRING_LENGTH) != 0);
+
+ Property::Array array;
+ for(auto i=0u; i<numStrings; ++i)
+ {
+ array.PushBack( encodedString.substr( i*MAX_PROPERTY_STRING_LENGTH, MAX_PROPERTY_STRING_LENGTH));
+ }
+ value = array;
+ }
+ else
+ {
+ value = encodedString;
+ }
+}
+
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef DALI_TOOLKIT_BASE64_ENCODING_H
+#define DALI_TOOLKIT_BASE64_ENCODING_H
+
+/*
+ * Copyright (c) 2018 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 <dali/public-api/object/property.h>
+#include <dali/public-api/common/vector-wrapper.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+/**
+ * @brief Parses a Property::STRING or Property::ARRAY of STRINGS to
+ * retrieve a block of uint32_t data.
+ *
+ * Data can be encoded using the base64 encoding scheme to allow it to be used
+ * in JSON (The property system maps to JSON types).
+ *
+ * @param[in] value The property value to decode
+ * @param[out] outputData The output data block
+ * @return True if a data block was decoded successfully.
+ */
+bool DecodeBase64PropertyData( const Property::Value& value, std::vector<uint32_t>& outputData );
+
+/**
+ * @brief Convert a block of uint32_t data into a Property::STRING or ARRAY of STRINGs
+ * encoded using base64. This allows the data to be mapped to JSON easily.
+ *
+ * @param[out] value The value to write data into (to avoid copying).
+ * @param[in] inputData The input
+ */
+void EncodeBase64PropertyData( Property::Value& value, const std::vector<uint32_t>& inputData );
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+
+#endif // DALI_TOOLKIT_BASE64_ENCODING_H
# Add local source files here
devel_api_src_files = \
+ $(devel_api_src_dir)/builder/base64-encoding.cpp \
$(devel_api_src_dir)/builder/builder.cpp \
$(devel_api_src_dir)/builder/json-parser.cpp \
$(devel_api_src_dir)/builder/tree-node.cpp \
$(devel_api_src_dir)/controls/buttons/toggle-button.h
devel_api_builder_header_files = \
+ $(devel_api_src_dir)/builder/base64-encoding.h \
$(devel_api_src_dir)/builder/builder.h \
$(devel_api_src_dir)/builder/json-parser.h \
$(devel_api_src_dir)/builder/tree-node.h
Property::Map transformMap = Property::Map();
Extents padding = Self().GetProperty<Extents>( Toolkit::Control::Property::PADDING );
+ const Visual::FittingMode fittingMode = Toolkit::GetImplementation(mVisual).GetFittingMode();
- Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>(
- Self().GetProperty( Dali::Actor::Property::LAYOUT_DIRECTION ).Get<int>() );
-
- if( Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection )
+ if( ( padding != Extents() ) || // If padding is not zero
+ ( fittingMode == Visual::FittingMode::FIT_KEEP_ASPECT_RATIO ) )
{
- std::swap( padding.start, padding.end );
- }
+ Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>(
+ Self().GetProperty( Dali::Actor::Property::LAYOUT_DIRECTION ).Get<int>() );
- auto finalOffset = Vector2( padding.start, padding.top );
+ if( Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection )
+ {
+ std::swap( padding.start, padding.end );
+ }
- // remove padding from the size to know how much is left for the visual
- auto finalSize = size - Vector2( padding.start + padding.end, padding.top + padding.bottom );
+ auto finalOffset = Vector2( padding.start, padding.top );
- // Should provide a transform that handles aspect ratio according to image size
- if( Toolkit::GetImplementation(mVisual).GetFittingMode() == Visual::FittingMode::FIT_KEEP_ASPECT_RATIO )
- {
- auto availableVisualSize = finalSize;
+ // remove padding from the size to know how much is left for the visual
+ auto finalSize = size - Vector2( padding.start + padding.end, padding.top + padding.bottom );
- Vector2 naturalSize;
- mVisual.GetNaturalSize( naturalSize );
+ // Should provide a transform that handles aspect ratio according to image size
+ if( fittingMode == Visual::FittingMode::FIT_KEEP_ASPECT_RATIO )
+ {
+ auto availableVisualSize = finalSize;
- // scale to fit the padded area
- finalSize = naturalSize * std::min( ( naturalSize.width ? ( availableVisualSize.width / naturalSize.width ) : 0 ),
- ( naturalSize.height ? ( availableVisualSize.height / naturalSize.height ) : 0 ) );
+ Vector2 naturalSize;
+ mVisual.GetNaturalSize( naturalSize );
- // calculate final offset within the padded area
- finalOffset += ( availableVisualSize - finalSize ) * .5f;
- }
+ // scale to fit the padded area
+ finalSize = naturalSize * std::min( ( naturalSize.width ? ( availableVisualSize.width / naturalSize.width ) : 0 ),
+ ( naturalSize.height ? ( availableVisualSize.height / naturalSize.height ) : 0 ) );
- // populate the transform map
- transformMap.Add( Toolkit::Visual::Transform::Property::OFFSET, finalOffset )
- .Add( Toolkit::Visual::Transform::Property::OFFSET_POLICY,
- Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) )
- .Add( Toolkit::Visual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
- .Add( Toolkit::Visual::Transform::Property::ANCHOR_POINT, Toolkit::Align::TOP_BEGIN )
- .Add( Toolkit::Visual::Transform::Property::SIZE, finalSize )
- .Add( Toolkit::Visual::Transform::Property::SIZE_POLICY,
- Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) );
+ // calculate final offset within the padded area
+ finalOffset += ( availableVisualSize - finalSize ) * .5f;
+ }
+
+ // populate the transform map
+ transformMap.Add( Toolkit::Visual::Transform::Property::OFFSET, finalOffset )
+ .Add( Toolkit::Visual::Transform::Property::OFFSET_POLICY,
+ Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) )
+ .Add( Toolkit::Visual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
+ .Add( Toolkit::Visual::Transform::Property::ANCHOR_POINT, Toolkit::Align::TOP_BEGIN )
+ .Add( Toolkit::Visual::Transform::Property::SIZE, finalSize )
+ .Add( Toolkit::Visual::Transform::Property::SIZE_POLICY,
+ Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) );
+ }
mVisual.SetTransformAndSize( transformMap, size );
}
AtlasUploadObserver* atlasObserver = nullptr;
ImageAtlasManagerPtr imageAtlasManager = nullptr;
Vector4 textureRect;
+ Dali::ImageDimensions textureRectSize;
auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
mTextureManager.LoadTexture(
url, ImageDimensions(), FittingMode::SCALE_TO_FILL,
SamplingMode::BOX_THEN_LINEAR, maskInfo,
- synchronousLoading, mImageUrls[ mUrlIndex ].mTextureId, textureRect,
+ synchronousLoading, mImageUrls[ mUrlIndex ].mTextureId, textureRect, textureRectSize,
atlasingStatus, loadingStatus, Dali::WrapMode::Type::DEFAULT,
Dali::WrapMode::Type::DEFAULT, this,
atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED,
AtlasUploadObserver* atlasObserver = nullptr;
ImageAtlasManagerPtr imageAtlasManager = nullptr;
Vector4 textureRect;
+ Dali::ImageDimensions textureRectSize;
auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
mTextureManager.LoadTexture(
mImageUrls[ imageFrame.mFrameNumber ].mUrl, ImageDimensions(), FittingMode::SCALE_TO_FILL,
SamplingMode::BOX_THEN_LINEAR, maskInfo,
- synchronousLoading, mImageUrls[ imageFrame.mFrameNumber ].mTextureId, textureRect,
+ synchronousLoading, mImageUrls[ imageFrame.mFrameNumber ].mTextureId, textureRect, textureRectSize,
atlasingStatus, loadingStatus, Dali::WrapMode::Type::DEFAULT,
Dali::WrapMode::Type::DEFAULT, NULL,
atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, preMultiply );
AtlasUploadObserver* atlasObserver = nullptr;
ImageAtlasManagerPtr imageAtlasManager = nullptr;
Vector4 textureRect;
+ Dali::ImageDimensions textureRectSize;
auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
mTextureManager.LoadTexture(
url, ImageDimensions(), FittingMode::SCALE_TO_FILL,
SamplingMode::BOX_THEN_LINEAR, maskInfo,
- synchronousLoading, mImageUrls[ imageFrame.mUrlIndex ].mTextureId, textureRect,
+ synchronousLoading, mImageUrls[ imageFrame.mUrlIndex ].mTextureId, textureRect, textureRectSize,
atlasingStatus, loadingStatus, Dali::WrapMode::Type::DEFAULT,
Dali::WrapMode::Type::DEFAULT, this,
atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED,
TextureSet ImageAtlasManager::Add( Vector4& textureRect,
const std::string& url,
- ImageDimensions size,
+ ImageDimensions& size,
FittingMode::Type fittingMode,
bool orientationCorrection,
AtlasUploadObserver* atlasUploadObserver )
{
return TextureSet();
}
+ size = dimensions;
unsigned int i = 0;
for( AtlasContainer::iterator iter = mAtlasList.begin(); iter != mAtlasList.end(); ++iter)
*
* @param [out] textureRect The texture area of the resource image in the atlas.
* @param [in] url The URL of the resource image file to use.
- * @param [in] size The width and height to fit the loaded image to.
+ * @param [in, out] size The width and height to fit the loaded image to.
* @param [in] fittingMode The method used to fit the shape of the image before loading to the shape defined by the size parameter.
* @param [in] orientationCorrection Reorient the image to respect any orientation metadata in its header.
* @param [in] atlasUploadObserver The object to observe the uploading state inside ImageAtlas.
*/
TextureSet Add( Vector4& textureRect,
const std::string& url,
- ImageDimensions size = ImageDimensions(),
+ ImageDimensions& size,
FittingMode::Type fittingMode = FittingMode::DEFAULT,
bool orientationCorrection = true,
AtlasUploadObserver* atlasUploadObserver = NULL );
mLoadPolicy( Toolkit::ImageVisual::LoadPolicy::ATTACHED ),
mReleasePolicy( Toolkit::ImageVisual::ReleasePolicy::DETACHED ),
mAtlasRect( 0.0f, 0.0f, 0.0f, 0.0f ),
+ mAtlasRectSize( 0, 0 ),
mAttemptAtlasing( false ),
mLoading( false ),
mOrientationCorrection( true )
}
else if( mImpl->mRenderer ) // Check if we have a loaded image
{
- auto textureSet = mImpl->mRenderer.GetTextures();
+ if( mImpl->mFlags & Impl::IS_ATLASING_APPLIED )
+ {
+ naturalSize.x = mAtlasRectSize.GetWidth();
+ naturalSize.y = mAtlasRectSize.GetHeight();
+ return;
+ }
+ auto textureSet = mImpl->mRenderer.GetTextures();
if( textureSet )
{
auto texture = textureSet.GetTexture(0);
textures = textureManager.LoadTexture( mImageUrl, mDesiredSize, mFittingMode, mSamplingMode,
mMaskingData, IsSynchronousResourceLoading(), mTextureId,
- atlasRect, atlasing, mLoading, mWrapModeU,
+ atlasRect, mAtlasRectSize, atlasing, mLoading, mWrapModeU,
mWrapModeV, textureObserver, atlasUploadObserver, atlasManager,
mOrientationCorrection, forceReload, preMultiplyOnLoad);
Dali::Toolkit::ImageVisual::LoadPolicy::Type mLoadPolicy;
Dali::Toolkit::ImageVisual::ReleasePolicy::Type mReleasePolicy;
Vector4 mAtlasRect;
+ Dali::ImageDimensions mAtlasRectSize;
bool mAttemptAtlasing; ///< If true will attempt atlasing, otherwise create unique texture
bool mLoading; ///< True if the texture is still loading.
bool mOrientationCorrection; ///< true if the image will have it's orientation corrected.
const VisualUrl& url, Dali::ImageDimensions desiredSize, Dali::FittingMode::Type fittingMode,
Dali::SamplingMode::Type samplingMode, const MaskingDataPointer& maskInfo,
bool synchronousLoading, TextureManager::TextureId& textureId, Vector4& textureRect,
- bool& atlasingStatus, bool& loadingStatus, Dali::WrapMode::Type wrapModeU,
- Dali::WrapMode::Type wrapModeV, TextureUploadObserver* textureObserver,
+ Dali::ImageDimensions& textureRectSize, bool& atlasingStatus, bool& loadingStatus,
+ Dali::WrapMode::Type wrapModeU, Dali::WrapMode::Type wrapModeV, TextureUploadObserver* textureObserver,
AtlasUploadObserver* atlasObserver, ImageAtlasManagerPtr imageAtlasManager, bool orientationCorrection,
TextureManager::ReloadPolicy reloadPolicy, TextureManager::MultiplyOnLoad& preMultiplyOnLoad )
{
textureSet = TextureSet::New();
textureSet.SetTexture( 0u, texture );
}
+ else
+ {
+ textureRectSize.SetWidth(data.GetWidth());
+ textureRectSize.SetHeight(data.GetHeight());
+ }
}
}
else
loadingStatus = true;
if( atlasingStatus )
{
- textureSet = imageAtlasManager->Add( textureRect, url.GetUrl(), desiredSize, fittingMode, true, atlasObserver );
+ textureSet = imageAtlasManager->Add( textureRect, url.GetUrl(), desiredSize, fittingMode, true, atlasObserver);
}
if( !textureSet ) // big image, no atlasing or atlasing failed
{
textureSet = GetTextureSet( textureId );
}
}
+ else
+ {
+ textureRectSize = desiredSize;
+ }
}
if( ! atlasingStatus && textureSet )
* @param[in] maskInfo Mask info structure
* @param[in] synchronousLoading true if the URL should be loaded synchronously
* @param[out] textureId, The textureId of the URL
- * @param[out] textureRect The rectangle within the texture atlas that this URL occupies
+ * @param[out] textureRect The rectangle within the texture atlas that this URL occupies,
+ * this is the rectangle in normalized coordinates.
+ * @param[out] textureRectSize The rectangle within the texture atlas that this URL occupies,
+ * this is the same rectangle in pixels.
* @param[in,out] atlasingStatus Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still
* be loaded, and marked successful, but this will be set to false.
* If atlasing succeeds, this will be set to true.
bool synchronousLoading,
TextureManager::TextureId& textureId,
Vector4& textureRect,
+ Dali::ImageDimensions& textureRectSize,
bool& atlasingStatus,
bool& loadingStatus,
Dali::WrapMode::Type wrapModeU,
const unsigned int TOOLKIT_MAJOR_VERSION = 1;
const unsigned int TOOLKIT_MINOR_VERSION = 3;
-const unsigned int TOOLKIT_MICRO_VERSION = 33;
+const unsigned int TOOLKIT_MICRO_VERSION = 34;
const char * const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
--- /dev/null
+/**
+ * base-n, 1.0
+ * Copyright (C) 2012 Andrzej Zawadzki (azawadzki@gmail.com)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+**/
+#ifndef BASEN_HPP
+#define BASEN_HPP
+
+#include <algorithm>
+#include <cctype>
+#include <cassert>
+#include <cstring>
+
+namespace bn
+{
+
+template<class Iter1, class Iter2>
+void encode_b16(Iter1 start, Iter1 end, Iter2 out);
+
+template<class Iter1, class Iter2>
+void encode_b32(Iter1 start, Iter1 end, Iter2 out);
+
+template<class Iter1, class Iter2>
+void encode_b64(Iter1 start, Iter1 end, Iter2 out);
+
+template<class Iter1, class Iter2>
+void decode_b16(Iter1 start, Iter1 end, Iter2 out);
+
+template<class Iter1, class Iter2>
+void decode_b32(Iter1 start, Iter1 end, Iter2 out);
+
+template<class Iter1, class Iter2>
+void decode_b64(Iter1 start, Iter1 end, Iter2 out);
+
+namespace impl
+{
+
+const int Error = -1;
+
+namespace {
+
+char extract_partial_bits(char value, size_t start_bit, size_t bits_count)
+{
+ assert(start_bit + bits_count < 8);
+ // shift extracted bits to the beginning of the byte
+ char t1 = value >> (8 - bits_count - start_bit);
+ // mask out bits on the left
+ char t2 = t1 & ~(0xff << bits_count);
+ return t2;
+}
+
+char extract_overlapping_bits(char previous, char next, size_t start_bit, size_t bits_count)
+{
+ assert(start_bit + bits_count < 16);
+ size_t bits_count_in_previous = 8 - start_bit;
+ size_t bits_count_in_next = bits_count - bits_count_in_previous;
+ char t1 = previous << bits_count_in_next;
+ char t2 = next >> (8 - bits_count_in_next) & ~(0xff << bits_count_in_next) ;
+ return (t1 | t2) & ~(0xff << bits_count);
+}
+
+}
+
+struct b16_conversion_traits
+{
+ static size_t group_length()
+ {
+ return 4;
+ }
+
+ static char encode(unsigned int index)
+ {
+ const char* const dictionary = "0123456789ABCDEF";
+ assert(index < strlen(dictionary));
+ return dictionary[index];
+ }
+
+ static char decode(char c)
+ {
+ if (c >= '0' && c <= '9') {
+ return c - '0';
+ } else if (c >= 'A' && c <= 'F') {
+ return c - 'A' + 10;
+ }
+ return Error;
+ }
+};
+
+struct b32_conversion_traits
+{
+ static size_t group_length()
+ {
+ return 5;
+ }
+
+ static char encode(unsigned int index)
+ {
+ const char * dictionary = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
+ assert(index < strlen(dictionary));
+ return dictionary[index];
+ }
+
+ static char decode(char c)
+ {
+ if (c >= 'A' && c <= 'Z') {
+ return c - 'A';
+ } else if (c >= '2' && c <= '7') {
+ return c - '2' + 26;
+ }
+ return Error;
+ }
+};
+
+struct b64_conversion_traits
+{
+ static size_t group_length()
+ {
+ return 6;
+ }
+
+ static char encode(unsigned int index)
+ {
+ const char* const dictionary = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ assert(index < strlen(dictionary));
+ return dictionary[index];
+ }
+
+ static char decode(char c)
+ {
+ const int alph_len = 26;
+ if (c >= 'A' && c <= 'Z') {
+ return c - 'A';
+ } else if (c >= 'a' && c <= 'z') {
+ return c - 'a' + alph_len * 1;
+ } else if (c >= '0' && c <= '9') {
+ return c - '0' + alph_len * 2;
+ } else if (c == '+') {
+ return c - '+' + alph_len * 2 + 10;
+ } else if (c == '/') {
+ return c - '/' + alph_len * 2 + 11;
+ }
+ return Error;
+ }
+};
+
+template<class ConversionTraits, class Iter1, class Iter2>
+void decode(Iter1 start, Iter1 end, Iter2 out)
+{
+ Iter1 iter = start;
+ size_t output_current_bit = 0;
+ char buffer = 0;
+
+ while (iter != end) {
+ if (std::isspace(*iter)) {
+ ++iter;
+ continue;
+ }
+ char value = ConversionTraits::decode(*iter);
+ if (value == Error) {
+ // malformed data, but let's go on...
+ ++iter;
+ continue;
+ }
+ size_t bits_in_current_byte = std::min<size_t>(output_current_bit + ConversionTraits::group_length(), 8) - output_current_bit;
+ if (bits_in_current_byte == ConversionTraits::group_length()) {
+ // the value fits within current byte, so we can extract it directly
+ buffer |= value << (8 - output_current_bit - ConversionTraits::group_length());
+ output_current_bit += ConversionTraits::group_length();
+ // check if we filled up current byte completely; in such case we flush output and continue
+ if (output_current_bit == 8) {
+ *out++ = buffer;
+ buffer = 0;
+ output_current_bit = 0;
+ }
+ } else {
+ // the value spans across the current and the next byte
+ size_t bits_in_next_byte = ConversionTraits::group_length() - bits_in_current_byte;
+ // fill the current byte and flush it to our output
+ buffer |= value >> bits_in_next_byte;
+ *out++ = buffer;
+ buffer = 0;
+ // save the remainder of our value in the buffer; it will be flushed
+ // during next iterations
+ buffer |= value << (8 - bits_in_next_byte);
+ output_current_bit = bits_in_next_byte;
+ }
+ ++iter;
+ }
+}
+
+template<class ConversionTraits, class Iter1, class Iter2>
+void encode(Iter1 start, Iter1 end, Iter2 out)
+{
+ Iter1 iter = start;
+ size_t start_bit = 0;
+ bool has_backlog = false;
+ char backlog = 0;
+
+ while (has_backlog || iter != end) {
+ if (!has_backlog) {
+ if (start_bit + ConversionTraits::group_length() < 8) {
+ // the value fits within single byte, so we can extract it
+ // directly
+ char v = extract_partial_bits(*iter, start_bit, ConversionTraits::group_length());
+ *out++ = ConversionTraits::encode(v);
+ // since we know that start_bit + ConversionTraits::group_length() < 8 we don't need to go
+ // to the next byte
+ start_bit += ConversionTraits::group_length();
+ } else {
+ // our bits are spanning across byte border; we need to keep the
+ // starting point and move over to next byte.
+ backlog = *iter++;
+ has_backlog = true;
+ }
+ } else {
+ // encode value which is made from bits spanning across byte
+ // boundary
+ char v;
+ if (iter == end)
+ v = extract_overlapping_bits(backlog, 0, start_bit, ConversionTraits::group_length());
+ else
+ v = extract_overlapping_bits(backlog, *iter, start_bit, ConversionTraits::group_length());
+ *out++ = ConversionTraits::encode(v);
+ has_backlog = false;
+ start_bit = (start_bit + ConversionTraits::group_length()) % 8;
+ }
+ }
+}
+
+} // impl
+
+using namespace bn::impl;
+
+template<class Iter1, class Iter2>
+void encode_b16(Iter1 start, Iter1 end, Iter2 out)
+{
+ encode<b16_conversion_traits>(start, end, out);
+}
+
+template<class Iter1, class Iter2>
+void encode_b32(Iter1 start, Iter1 end, Iter2 out)
+{
+ encode<b32_conversion_traits>(start, end, out);
+}
+
+template<class Iter1, class Iter2>
+void encode_b64(Iter1 start, Iter1 end, Iter2 out)
+{
+ encode<b64_conversion_traits>(start, end, out);
+}
+
+template<class Iter1, class Iter2>
+void decode_b16(Iter1 start, Iter1 end, Iter2 out)
+{
+ decode<b16_conversion_traits>(start, end, out);
+}
+
+template<class Iter1, class Iter2>
+void decode_b32(Iter1 start, Iter1 end, Iter2 out)
+{
+ decode<b32_conversion_traits>(start, end, out);
+}
+
+template<class Iter1, class Iter2>
+void decode_b64(Iter1 start, Iter1 end, Iter2 out)
+{
+ decode<b64_conversion_traits>(start, end, out);
+}
+
+} // bn
+
+#endif // BASEN_HPP
Name: dali-toolkit
Summary: Dali 3D engine Toolkit
-Version: 1.3.33
+Version: 1.3.34
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-3-Clause and MIT