Merge "C# Bindings for Transition Policy properties" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / npatch-loader.cpp
1  /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali-toolkit/internal/visuals/npatch-loader.h>
20
21 // EXTERNAL HEADER
22 #include <dali/devel-api/common/hash.h>
23 #include <dali/devel-api/images/texture-set-image.h>
24 #include <dali-toolkit/public-api/image-loader/sync-image-loader.h>
25
26 namespace Dali
27 {
28
29 namespace Toolkit
30 {
31
32 namespace Internal
33 {
34
35 NPatchLoader::NPatchLoader()
36 {
37 }
38
39 NPatchLoader::~NPatchLoader()
40 {
41 }
42
43 std::size_t NPatchLoader::Load( const std::string& url, const Rect< int >& border )
44 {
45   std::size_t hash = CalculateHash( url );
46   OwnerContainer< Data* >::SizeType index = UNINITIALIZED_ID;
47   const OwnerContainer< Data* >::SizeType count = mCache.Count();
48   for( ; index < count; ++index )
49   {
50     if( mCache[ index ]->hash == hash )
51     {
52       // hash match, check url as well in case of hash collision
53       if( mCache[ index ]->url == url )
54       {
55         return index+1u; // valid indices are from 1 onwards
56       }
57     }
58   }
59   // got to the end so no match, decode N patch and append new item to cache
60   if( border == Rect< int >( 0, 0, 0, 0 ) )
61   {
62     NinePatchImage ninePatch = NinePatchImage::New( url );
63     if( ninePatch )
64     {
65       BufferImage croppedImage = ninePatch.CreateCroppedBufferImage();
66       if( croppedImage )
67       {
68         Data* data = new Data();
69         data->hash = hash;
70         data->url = url;
71         data->textureSet = TextureSet::New();
72         TextureSetImage( data->textureSet, 0u, croppedImage );
73         data->croppedWidth = croppedImage.GetWidth();
74         data->croppedHeight = croppedImage.GetHeight();
75         data->stretchPixelsX = ninePatch.GetStretchPixelsX();
76         data->stretchPixelsY = ninePatch.GetStretchPixelsY();
77         mCache.PushBack( data );
78
79         return mCache.Count(); // valid ids start from 1u
80       }
81     }
82   }
83   else
84   {
85     // Load image from file
86     PixelData pixels = SyncImageLoader::Load( url );
87     if( pixels )
88     {
89       Data* data = new Data();
90       data->hash = hash;
91       data->url = url;
92       data->croppedWidth = pixels.GetWidth();
93       data->croppedHeight = pixels.GetHeight();
94
95       Texture texture = Texture::New( TextureType::TEXTURE_2D, pixels.GetPixelFormat(), pixels.GetWidth(), pixels.GetHeight() );
96       texture.Upload( pixels, 0, 0, 0, 0, pixels.GetWidth(), pixels.GetHeight() );
97
98       data->textureSet = TextureSet::New();
99       data->textureSet.SetTexture( 0u, texture );
100
101       NinePatchImage::StretchRanges stretchRangesX;
102       stretchRangesX.PushBack( Uint16Pair( border.left, data->croppedWidth - border.right ) );
103
104       NinePatchImage::StretchRanges stretchRangesY;
105       stretchRangesY.PushBack( Uint16Pair( border.top, data->croppedHeight - border.bottom ) );
106
107       data->stretchPixelsX = stretchRangesX;
108       data->stretchPixelsY = stretchRangesY;
109
110       mCache.PushBack( data );
111
112       return mCache.Count(); // valid ids start from 1u
113     }
114   }
115
116   return 0u;
117 }
118
119 bool NPatchLoader::GetNPatchData( std::size_t id, const Data*& data )
120 {
121   if( ( id > UNINITIALIZED_ID )&&( id <= mCache.Count() ) )
122   {
123     data = mCache[ id - 1u ]; // id's start from 1u
124     return true;
125   }
126   data = NULL;
127   return false;
128 }
129
130 } // namespace Internal
131
132 } // namespace Toolkit
133
134 } // namespace Dali