Remove RenderSurface from Core
[platform/core/uifw/dali-core.git] / automated-tests / src / dali / utc-Dali-NinePatchImages.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 #include <iostream>
19
20 #include <stdlib.h>
21 #include <dali/public-api/dali-core.h>
22 #include <dali/devel-api/images/nine-patch-image.h>
23 #include <dali-test-suite-utils.h>
24
25 using namespace Dali;
26
27 namespace {
28
29 Integration::Bitmap* CreateBitmap( unsigned int imageWidth, unsigned int imageHeight, unsigned int initialColor, Pixel::Format pixelFormat )
30 {
31   Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::OWNED_RETAIN );
32   Integration::PixelBuffer* pixbuffer = bitmap->GetPackedPixelsProfile()->ReserveBuffer( pixelFormat, imageWidth, imageHeight, imageWidth, imageHeight );
33   unsigned int bytesPerPixel = GetBytesPerPixel( pixelFormat );
34
35   memset( pixbuffer, initialColor, imageHeight * imageWidth * bytesPerPixel );
36
37   return bitmap;
38 }
39
40 void InitialiseRegionsToZeroAlpha( Integration::Bitmap* image, unsigned int imageWidth, unsigned int imageHeight, Pixel::Format pixelFormat )
41 {
42   PixelBuffer* pixbuffer = image->GetBuffer();
43   unsigned int bytesPerPixel = GetBytesPerPixel( pixelFormat );
44
45   for( unsigned int row = 0; row < imageWidth; ++row )
46   {
47     unsigned int pixelOffset = row * bytesPerPixel;
48     pixbuffer[ pixelOffset + 3 ] = 0x00;
49     pixelOffset += ( imageHeight - 1 ) * imageWidth * bytesPerPixel;
50     pixbuffer[ pixelOffset + 3 ] = 0x00;
51   }
52
53   for ( unsigned int column = 0; column < imageHeight; ++column )
54   {
55     unsigned int pixelOffset = column * imageWidth * bytesPerPixel;
56     pixbuffer[ pixelOffset + 3 ] = 0x00;
57     pixelOffset += ( imageWidth -1 ) * bytesPerPixel;
58     pixbuffer[ pixelOffset + 3 ] = 0x00;
59   }
60 }
61
62 void AddStretchRegionsToImage( Integration::Bitmap* image, unsigned int imageWidth, unsigned int imageHeight, const Vector4& requiredStretchBorder, Pixel::Format pixelFormat )
63 {
64   PixelBuffer* pixbuffer = image->GetBuffer();
65   unsigned int bytesPerPixel = GetBytesPerPixel( pixelFormat );
66
67   for( unsigned int column = requiredStretchBorder.x; column < imageWidth - requiredStretchBorder.z; ++column )
68   {
69     unsigned int pixelOffset = column * bytesPerPixel;
70     pixbuffer[ pixelOffset ] = 0x00;
71     pixbuffer[ pixelOffset + 1 ] = 0x00;
72     pixbuffer[ pixelOffset + 2 ] = 0x00;
73     pixbuffer[ pixelOffset + 3 ] = 0xFF;
74   }
75
76   for( unsigned int row = requiredStretchBorder.y; row < imageHeight - requiredStretchBorder.w; ++row )
77   {
78     unsigned int pixelOffset = row * imageWidth * bytesPerPixel;
79     pixbuffer[ pixelOffset ] = 0x00;
80     pixbuffer[ pixelOffset + 1 ] = 0x00;
81     pixbuffer[ pixelOffset + 2 ] = 0x00;
82     pixbuffer[ pixelOffset + 3 ] = 0xFF;
83   }
84 }
85
86 void AddChildRegionsToImage( Integration::Bitmap* image, unsigned int imageWidth, unsigned int imageHeight, const Vector4& requiredChildRegion, Pixel::Format pixelFormat )
87 {
88   PixelBuffer* pixbuffer = image->GetBuffer();
89   unsigned int bytesPerPixel = GetBytesPerPixel( pixelFormat );
90
91   Integration::Bitmap::PackedPixelsProfile* srcProfile = image->GetPackedPixelsProfile();
92   unsigned int bufferStride = srcProfile->GetBufferStride();
93
94   // Add bottom child region
95   for( unsigned int column = requiredChildRegion.x; column < imageWidth - requiredChildRegion.z; ++column )
96   {
97     unsigned int pixelOffset = column * bytesPerPixel;
98     pixelOffset += ( imageHeight - 1 ) * bufferStride;
99     pixbuffer[ pixelOffset ] = 0x00;
100     pixbuffer[ pixelOffset + 1 ] = 0x00;
101     pixbuffer[ pixelOffset + 2 ] = 0x00;
102     pixbuffer[ pixelOffset + 3 ] = 0xFF;
103   }
104
105   // Add right child region
106   for ( unsigned int row = requiredChildRegion.y; row < imageHeight - requiredChildRegion.w; ++row )
107   {
108     unsigned int pixelOffset = row * bufferStride + ( imageWidth - 1 ) * bytesPerPixel;
109     pixbuffer[ pixelOffset ] = 0x00;
110     pixbuffer[ pixelOffset + 1 ] = 0x00;
111     pixbuffer[ pixelOffset + 2 ] = 0x00;
112     pixbuffer[ pixelOffset + 3 ] = 0xFF;
113   }
114 }
115
116 NinePatchImage CustomizeNinePatch( TestApplication& application,
117                                 unsigned int ninePatchImageWidth,
118                                 unsigned int ninePatchImageHeight,
119                                 const Vector4& requiredStretchBorder,
120                                 bool addChildRegion = false,
121                                 Vector4 requiredChildRegion = Vector4::ZERO )
122 {
123   TestPlatformAbstraction& platform = application.GetPlatform();
124
125   Pixel::Format pixelFormat = Pixel::RGBA8888;
126
127   tet_infoline("Create Bitmap");
128   platform.SetClosestImageSize(Vector2( ninePatchImageWidth, ninePatchImageHeight));
129   Integration::Bitmap* bitmap = CreateBitmap( ninePatchImageWidth, ninePatchImageHeight, 0xFF, pixelFormat );
130
131   tet_infoline("Clear border regions");
132   InitialiseRegionsToZeroAlpha( bitmap, ninePatchImageWidth, ninePatchImageHeight, pixelFormat );
133
134   tet_infoline("Add Stretch regions to Bitmap");
135   AddStretchRegionsToImage( bitmap, ninePatchImageWidth, ninePatchImageHeight, requiredStretchBorder, pixelFormat );
136
137   if( addChildRegion )
138   {
139     tet_infoline("Add Child regions to Bitmap");
140     AddChildRegionsToImage( bitmap, ninePatchImageWidth, ninePatchImageHeight, requiredChildRegion, pixelFormat );
141   }
142
143   tet_infoline("Setting resource as it's loaded synchronously");
144   Integration::ResourcePointer resourcePtr(bitmap);
145   platform.SetSynchronouslyLoadedResource( resourcePtr );
146
147   std::string url( "blah.#.png" );
148   Image image = ResourceImage::New( url );
149
150   tet_infoline("Assign image to image rendering actor");
151   Actor actor = CreateRenderableActor( image );
152   Stage::GetCurrent().Add( actor );
153
154   tet_infoline("Downcast Image to a nine-patch image\n");
155   NinePatchImage ninePatchImage = NinePatchImage::DownCast( image );
156
157   DALI_TEST_EQUALS( url, ninePatchImage.GetUrl(), TEST_LOCATION );
158
159   return ninePatchImage;
160
161 }
162
163 } // namespace
164
165 int UtcDaliNinePatchImageNew(void)
166 {
167   TestApplication application;
168   tet_infoline("UtcDaliNinePatchImageNew - NinePatchImage::New(const std::string&)");
169
170   // invoke default handle constructor
171   NinePatchImage image;
172
173   DALI_TEST_CHECK( !image );
174
175   // initialise handle
176   std::string url("blah.#.png");
177   image = NinePatchImage::New( url );
178
179   DALI_TEST_CHECK( image );
180
181   DALI_TEST_EQUALS( url, image.GetUrl(), TEST_LOCATION );
182
183   END_TEST;
184 }
185
186 int UtcDaliNinePatchImageDowncast(void)
187 {
188   TestApplication application;
189   tet_infoline("UtcDaliNinePatchImageDowncast - NinePatchImage::DownCast(BaseHandle)");
190
191   NinePatchImage image = NinePatchImage::New( "blah.#.png" );
192
193   BaseHandle object( image );
194
195   NinePatchImage image2 = NinePatchImage::DownCast( object );
196   DALI_TEST_CHECK( image2 );
197
198   NinePatchImage image3 = DownCast< NinePatchImage >( object );
199   DALI_TEST_CHECK( image3 );
200
201   BaseHandle unInitializedObject;
202   NinePatchImage image4 = NinePatchImage::DownCast( unInitializedObject );
203   DALI_TEST_CHECK( !image4 );
204
205   NinePatchImage image5 = DownCast< NinePatchImage >( unInitializedObject );
206   DALI_TEST_CHECK( !image5 );
207
208   Image image6 = NinePatchImage::New( "blah.#.png" );
209   NinePatchImage image7 = NinePatchImage::DownCast( image6 );
210   DALI_TEST_CHECK( image7 );
211   END_TEST;
212 }
213
214 int UtcDaliNinePatchImageCopyConstructor(void)
215 {
216   TestApplication application;
217
218   tet_infoline("UtcDaliNinePatchImageCopyConstructor - NinePatchImage::NinePatchImage( const NinePatchImage& )");
219
220   NinePatchImage image1;
221   DALI_TEST_CHECK( !image1 );
222
223   image1 = NinePatchImage::New( "blah.#.png" );
224   NinePatchImage image2( image1 );
225
226   DALI_TEST_CHECK( image2 );
227   DALI_TEST_EQUALS( image1, image2, TEST_LOCATION );
228
229   END_TEST;
230 }
231
232 int UtcDaliNinePatchImageGetStrechBorders(void)
233 {
234   TestApplication application;
235   tet_infoline("UtcDaliNinePatchImageGetStrechBorders - NinePatchImage::GetStretchBorders()");
236
237   /* Stretch region left(2) top(2) right (2) bottom (2)
238     *    ss
239     *  OOOOOO
240     *  OOOOOOc
241     * sOOooOOc
242     * sOOooOOc
243     *  OOOOOOc
244     *  OOOOOO
245     *   cccc
246     */
247
248    const unsigned int ninePatchImageHeight = 18;
249    const unsigned int ninePatchImageWidth = 28;
250    const Vector4 requiredStretchBorder( 3, 4, 5, 6 );
251
252    NinePatchImage ninePatchImage = CustomizeNinePatch( application, ninePatchImageWidth, ninePatchImageHeight, requiredStretchBorder );
253    DALI_TEST_CHECK( ninePatchImage );
254
255    if( ninePatchImage )
256    {
257      tet_infoline("Get Stretch regions from NinePatch");
258
259      const NinePatchImage::StretchRanges& stretchPixelsX = ninePatchImage.GetStretchPixelsX();
260      const NinePatchImage::StretchRanges& stretchPixelsY = ninePatchImage.GetStretchPixelsY();
261
262      DALI_TEST_CHECK( stretchPixelsX.Size() == 1 );
263      DALI_TEST_CHECK( stretchPixelsY.Size() == 1 );
264
265      Vector4 stretchBorders;
266      //The NinePatchImage stretch pixels are in the cropped image space, inset by 1 to get it to uncropped image space
267      stretchBorders.x = stretchPixelsX[ 0 ].GetX() + 1;
268      stretchBorders.y = stretchPixelsY[ 0 ].GetX() + 1;
269      stretchBorders.z = ninePatchImageWidth - stretchPixelsX[ 0 ].GetY() - 1;
270      stretchBorders.w = ninePatchImageHeight - stretchPixelsY[ 0 ].GetY() - 1;
271
272      tet_printf("stretchBorders left(%f) right(%f) top(%f) bottom(%f)\n", stretchBorders.x, stretchBorders.z, stretchBorders.y, stretchBorders.w );
273      DALI_TEST_CHECK( stretchBorders == requiredStretchBorder );
274
275      Vector4 actualStretchBorders = ninePatchImage.GetStretchBorders();
276      DALI_TEST_EQUALS( actualStretchBorders, requiredStretchBorder, 0.001, TEST_LOCATION );
277    }
278    else
279    {
280      tet_infoline("Image not NinePatch");
281      test_return_value = TET_FAIL;
282    }
283
284   END_TEST;
285 }
286
287 int UtcDaliNinePatchImageGetChildRectangle(void)
288 {
289   TestApplication application;
290   tet_infoline("UtcDaliNinePatchImageGetChildRectangle - NinePatchImage::GetChildRectangle()");
291
292   /* Child region x(2) y(2) width (4) height (4)
293    *
294    *    ss
295    *  OOOOOO
296    *  OOOOOOc
297    * sOOooOOc
298    * sOOooOOc
299    *  OOOOOOc
300    *  OOOOOO
301    *   cccc
302    */
303
304   const unsigned int ninePatchImageHeight = 18;
305   const unsigned int ninePatchImageWidth = 28;
306   const Vector4 requiredChildRegion( 2, 2, 2, 2 );
307   const Vector4 requiredStretchBorder( 3, 4, 5, 6 );
308
309   NinePatchImage ninePatchImage = CustomizeNinePatch( application,ninePatchImageWidth, ninePatchImageHeight, requiredStretchBorder, true, requiredChildRegion );
310   DALI_TEST_CHECK( ninePatchImage );
311
312   if ( ninePatchImage )
313   {
314     tet_infoline("Get Child regions from NinePatch");
315     Rect< int > childRectangle = ninePatchImage.GetChildRectangle();
316     tet_printf("childRectange x(%d) y(%d) width(%d) height(%d)\n", childRectangle.x, childRectangle.y, childRectangle.width, childRectangle.height );
317     Rect< int > childRegion(requiredChildRegion.x, requiredChildRegion.y, ninePatchImageWidth - requiredChildRegion.x - requiredChildRegion.z, ninePatchImageHeight - requiredChildRegion.y - requiredChildRegion.w );
318     DALI_TEST_CHECK( childRegion == childRectangle );
319   }
320   else
321   {
322     tet_infoline("Image not NinePatch");
323     test_return_value = TET_FAIL;
324   }
325
326   END_TEST;
327 }
328
329 int UtcDaliNinePatchImageCreateCroppedBufferImage(void)
330 {
331   TestApplication application;
332   tet_infoline("UtcDaliNinePatchImageCreateCroppedBufferImage - NinePatchImage::CreateCroppedBufferImage()");
333
334   const unsigned int ninePatchImageHeight = 8;
335   const unsigned int ninePatchImageWidth = 8;
336   const Vector4 requiredStretchBorder( 1, 1, 1, 1 );
337
338   NinePatchImage ninePatchImage = CustomizeNinePatch( application, ninePatchImageWidth, ninePatchImageHeight, requiredStretchBorder  );
339   DALI_TEST_CHECK( ninePatchImage );
340
341   if ( ninePatchImage )
342   {
343     BufferImage newImage = ninePatchImage.CreateCroppedBufferImage();
344     DALI_TEST_CHECK( newImage );
345
346     DALI_TEST_EQUALS( newImage.GetPixelFormat(), Pixel::RGBA8888, TEST_LOCATION );
347
348     DALI_TEST_EQUALS( newImage.GetBufferSize(), 144u/* 36*4 */, TEST_LOCATION );
349   }
350   else
351   {
352     tet_infoline("Image not NinePatch");
353     test_return_value = TET_FAIL;
354   }
355
356   END_TEST;
357 }
358
359 int UtcDaliNinePatchImageIsNinePatchUrl(void)
360 {
361   TestApplication application;
362   tet_infoline("UtcDaliNinePatchImageIsNinePatchUrl - NinePatchImage::IsNinePatchUrl(const std::string&)");
363
364   DALI_TEST_CHECK( NinePatchImage::IsNinePatchUrl( "test.9.jpg" ) );
365   DALI_TEST_CHECK( NinePatchImage::IsNinePatchUrl( "test.#.jpg" ) );
366   DALI_TEST_CHECK( !NinePatchImage::IsNinePatchUrl( "test.9" ) );
367   DALI_TEST_CHECK( !NinePatchImage::IsNinePatchUrl( "test.#" ) );
368   DALI_TEST_CHECK( !NinePatchImage::IsNinePatchUrl( "test" ) );
369
370   END_TEST;
371 }