From: David Steele Date: Fri, 27 Jul 2018 11:43:34 +0000 (+0100) Subject: [dali_1.3.34] Merge branch 'devel/master' X-Git-Tag: dali_1.9.8~5^2~87 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=327e9280031da8874029123bf52ce2f31fb4ffd7;hp=3b021739c52d51158bfc3d9c6fc1dc6a2a03a160 [dali_1.3.34] Merge branch 'devel/master' Change-Id: I8852f7401acd7308ea91d64f185654eed55a7151 --- diff --git a/automated-tests/src/dali-toolkit/utc-Dali-Builder.cpp b/automated-tests/src/dali-toolkit/utc-Dali-Builder.cpp index 511d2ef..77439d4 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-Builder.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-Builder.cpp @@ -1,5 +1,5 @@ /* - * 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. @@ -16,14 +16,20 @@ */ #include -#include +#include +#include +#include +#include + #include #include +#include #include #include #include #include + #define STRINGIFY(A)#A using namespace Dali; @@ -1851,3 +1857,256 @@ int UtcDaliBuilderConfigurationP(void) END_TEST; } + + +int UtcDaliBase64EncodingP(void) +{ + std::vector data = { 0, 1, 2, 3, 4, 5, std::numeric_limits::min(), std::numeric_limits::max() }; + + Property::Value value; + EncodeBase64PropertyData( value, data ); + + std::cout << "Max uint32_t:" << std::numeric_limits::max() << std::endl; + std::cout << "Input data: "; + std::ostream_iterator 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 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 +int b64l(std::vector&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 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 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 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 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 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 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 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 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 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 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 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 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 expectedResults = { 0xffffffff, 0xfefefefe, 0x00010203 }; + + std::vector outputData; + DecodeBase64PropertyData(Property::Value(testInput), outputData); + + DALI_TEST_EQUALS( std::equal( expectedResults.begin(), expectedResults.end(), outputData.begin() ), true, + TEST_LOCATION ); + + END_TEST; +} diff --git a/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp b/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp index 02446a0..77121d5 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp @@ -1,5 +1,5 @@ /* - * 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. @@ -1708,3 +1708,70 @@ int UtcDaliImageViewPaddingProperty02(void) 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; +} diff --git a/dali-toolkit/devel-api/builder/base64-encoding.cpp b/dali-toolkit/devel-api/builder/base64-encoding.cpp new file mode 100644 index 0000000..2799430 --- /dev/null +++ b/dali-toolkit/devel-api/builder/base64-encoding.cpp @@ -0,0 +1,127 @@ +/* + * 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 +#include + +#include +#include +#include +#include + +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& outputData ) +{ + bool decoded = false; + std::string encodedString; + + + if( GetStringFromProperty( value, encodedString ) ) + { + std::vector 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& inputData ) +{ + std::ostringstream oss; + + bn::encode_b64( reinterpret_cast(&inputData[0]), + reinterpret_cast(&inputData[0]+inputData.size()), + std::ostream_iterator(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 +#include + +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& 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& inputData ); + +} // namespace Toolkit + +} // namespace Dali + + +#endif // DALI_TOOLKIT_BASE64_ENCODING_H diff --git a/dali-toolkit/devel-api/file.list b/dali-toolkit/devel-api/file.list index 411afe1..e974720 100755 --- a/dali-toolkit/devel-api/file.list +++ b/dali-toolkit/devel-api/file.list @@ -1,6 +1,7 @@ # 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 \ @@ -73,6 +74,7 @@ devel_api_buttons_header_files = \ $(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 diff --git a/dali-toolkit/internal/controls/image-view/image-view-impl.cpp b/dali-toolkit/internal/controls/image-view/image-view-impl.cpp index 11d5389..f709559 100755 --- a/dali-toolkit/internal/controls/image-view/image-view-impl.cpp +++ b/dali-toolkit/internal/controls/image-view/image-view-impl.cpp @@ -271,45 +271,50 @@ void ImageView::OnRelayout( const Vector2& size, RelayoutContainer& container ) Property::Map transformMap = Property::Map(); Extents padding = Self().GetProperty( Toolkit::Control::Property::PADDING ); + const Visual::FittingMode fittingMode = Toolkit::GetImplementation(mVisual).GetFittingMode(); - Dali::LayoutDirection::Type layoutDirection = static_cast( - Self().GetProperty( Dali::Actor::Property::LAYOUT_DIRECTION ).Get() ); - - 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( + Self().GetProperty( Dali::Actor::Property::LAYOUT_DIRECTION ).Get() ); - 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 ); } diff --git a/dali-toolkit/internal/visuals/animated-image/fixed-image-cache.cpp b/dali-toolkit/internal/visuals/animated-image/fixed-image-cache.cpp index dd06d31..2fbfee1 100644 --- a/dali-toolkit/internal/visuals/animated-image/fixed-image-cache.cpp +++ b/dali-toolkit/internal/visuals/animated-image/fixed-image-cache.cpp @@ -116,12 +116,13 @@ void FixedImageCache::LoadBatch() 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, diff --git a/dali-toolkit/internal/visuals/animated-image/rolling-gif-image-cache.cpp b/dali-toolkit/internal/visuals/animated-image/rolling-gif-image-cache.cpp index 9f9e623..4854076 100644 --- a/dali-toolkit/internal/visuals/animated-image/rolling-gif-image-cache.cpp +++ b/dali-toolkit/internal/visuals/animated-image/rolling-gif-image-cache.cpp @@ -151,12 +151,13 @@ void RollingGifImageCache::LoadBatch() 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 ); diff --git a/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.cpp b/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.cpp index bee7234..596ff88 100644 --- a/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.cpp +++ b/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.cpp @@ -151,12 +151,13 @@ void RollingImageCache::LoadBatch() 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, diff --git a/dali-toolkit/internal/visuals/image-atlas-manager.cpp b/dali-toolkit/internal/visuals/image-atlas-manager.cpp index d959c1a..2e4dfb4 100644 --- a/dali-toolkit/internal/visuals/image-atlas-manager.cpp +++ b/dali-toolkit/internal/visuals/image-atlas-manager.cpp @@ -49,7 +49,7 @@ ImageAtlasManager::~ImageAtlasManager() TextureSet ImageAtlasManager::Add( Vector4& textureRect, const std::string& url, - ImageDimensions size, + ImageDimensions& size, FittingMode::Type fittingMode, bool orientationCorrection, AtlasUploadObserver* atlasUploadObserver ) @@ -68,6 +68,7 @@ TextureSet ImageAtlasManager::Add( Vector4& textureRect, { return TextureSet(); } + size = dimensions; unsigned int i = 0; for( AtlasContainer::iterator iter = mAtlasList.begin(); iter != mAtlasList.end(); ++iter) diff --git a/dali-toolkit/internal/visuals/image-atlas-manager.h b/dali-toolkit/internal/visuals/image-atlas-manager.h index 5907ca2..05ed3a5 100644 --- a/dali-toolkit/internal/visuals/image-atlas-manager.h +++ b/dali-toolkit/internal/visuals/image-atlas-manager.h @@ -64,7 +64,7 @@ public: * * @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. @@ -72,7 +72,7 @@ public: */ TextureSet Add( Vector4& textureRect, const std::string& url, - ImageDimensions size = ImageDimensions(), + ImageDimensions& size, FittingMode::Type fittingMode = FittingMode::DEFAULT, bool orientationCorrection = true, AtlasUploadObserver* atlasUploadObserver = NULL ); diff --git a/dali-toolkit/internal/visuals/image/image-visual.cpp b/dali-toolkit/internal/visuals/image/image-visual.cpp index 0e4f018..faeeaec 100644 --- a/dali-toolkit/internal/visuals/image/image-visual.cpp +++ b/dali-toolkit/internal/visuals/image/image-visual.cpp @@ -268,6 +268,7 @@ ImageVisual::ImageVisual( VisualFactoryCache& factoryCache, 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 ) @@ -588,8 +589,14 @@ void ImageVisual::GetNaturalSize( Vector2& naturalSize ) } 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); @@ -768,7 +775,7 @@ void ImageVisual::LoadTexture( bool& atlasing, Vector4& atlasRect, TextureSet& t 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); diff --git a/dali-toolkit/internal/visuals/image/image-visual.h b/dali-toolkit/internal/visuals/image/image-visual.h index 6e48997..dd63c16 100644 --- a/dali-toolkit/internal/visuals/image/image-visual.h +++ b/dali-toolkit/internal/visuals/image/image-visual.h @@ -374,6 +374,7 @@ private: 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. diff --git a/dali-toolkit/internal/visuals/texture-manager-impl.cpp b/dali-toolkit/internal/visuals/texture-manager-impl.cpp index a08b2c5..c617a51 100644 --- a/dali-toolkit/internal/visuals/texture-manager-impl.cpp +++ b/dali-toolkit/internal/visuals/texture-manager-impl.cpp @@ -134,8 +134,8 @@ TextureSet TextureManager::LoadTexture( 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 ) { @@ -205,6 +205,11 @@ TextureSet TextureManager::LoadTexture( textureSet = TextureSet::New(); textureSet.SetTexture( 0u, texture ); } + else + { + textureRectSize.SetWidth(data.GetWidth()); + textureRectSize.SetHeight(data.GetHeight()); + } } } else @@ -212,7 +217,7 @@ TextureSet TextureManager::LoadTexture( 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 { @@ -245,6 +250,10 @@ TextureSet TextureManager::LoadTexture( textureSet = GetTextureSet( textureId ); } } + else + { + textureRectSize = desiredSize; + } } if( ! atlasingStatus && textureSet ) diff --git a/dali-toolkit/internal/visuals/texture-manager-impl.h b/dali-toolkit/internal/visuals/texture-manager-impl.h index e56fec4..59d191e 100644 --- a/dali-toolkit/internal/visuals/texture-manager-impl.h +++ b/dali-toolkit/internal/visuals/texture-manager-impl.h @@ -175,7 +175,10 @@ public: * @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. @@ -203,6 +206,7 @@ public: bool synchronousLoading, TextureManager::TextureId& textureId, Vector4& textureRect, + Dali::ImageDimensions& textureRectSize, bool& atlasingStatus, bool& loadingStatus, Dali::WrapMode::Type wrapModeU, diff --git a/dali-toolkit/public-api/dali-toolkit-version.cpp b/dali-toolkit/public-api/dali-toolkit-version.cpp index 70e33f9..b13f65b 100644 --- a/dali-toolkit/public-api/dali-toolkit-version.cpp +++ b/dali-toolkit/public-api/dali-toolkit-version.cpp @@ -31,7 +31,7 @@ namespace Toolkit 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 diff --git a/dali-toolkit/third-party/base-n/basen.hpp b/dali-toolkit/third-party/base-n/basen.hpp new file mode 100644 index 0000000..3ed31e8 --- /dev/null +++ b/dali-toolkit/third-party/base-n/basen.hpp @@ -0,0 +1,289 @@ +/** + * 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 +#include +#include +#include + +namespace bn +{ + +template +void encode_b16(Iter1 start, Iter1 end, Iter2 out); + +template +void encode_b32(Iter1 start, Iter1 end, Iter2 out); + +template +void encode_b64(Iter1 start, Iter1 end, Iter2 out); + +template +void decode_b16(Iter1 start, Iter1 end, Iter2 out); + +template +void decode_b32(Iter1 start, Iter1 end, Iter2 out); + +template +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 +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(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 +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 +void encode_b16(Iter1 start, Iter1 end, Iter2 out) +{ + encode(start, end, out); +} + +template +void encode_b32(Iter1 start, Iter1 end, Iter2 out) +{ + encode(start, end, out); +} + +template +void encode_b64(Iter1 start, Iter1 end, Iter2 out) +{ + encode(start, end, out); +} + +template +void decode_b16(Iter1 start, Iter1 end, Iter2 out) +{ + decode(start, end, out); +} + +template +void decode_b32(Iter1 start, Iter1 end, Iter2 out) +{ + decode(start, end, out); +} + +template +void decode_b64(Iter1 start, Iter1 end, Iter2 out) +{ + decode(start, end, out); +} + +} // bn + +#endif // BASEN_HPP diff --git a/packaging/dali-toolkit.spec b/packaging/dali-toolkit.spec index ab7c82f..82a9ed9 100644 --- a/packaging/dali-toolkit.spec +++ b/packaging/dali-toolkit.spec @@ -1,6 +1,6 @@ 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