2 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
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>
29 Integration::Bitmap* CreateBitmap( unsigned int imageWidth, unsigned int imageHeight, unsigned int initialColor, Pixel::Format pixelFormat )
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 );
35 memset( pixbuffer, initialColor, imageHeight * imageWidth * bytesPerPixel );
40 void InitialiseRegionsToZeroAlpha( Integration::Bitmap* image, unsigned int imageWidth, unsigned int imageHeight, Pixel::Format pixelFormat )
42 PixelBuffer* pixbuffer = image->GetBuffer();
43 unsigned int bytesPerPixel = GetBytesPerPixel( pixelFormat );
45 for( unsigned int row = 0; row < imageWidth; ++row )
47 unsigned int pixelOffset = row * bytesPerPixel;
48 pixbuffer[ pixelOffset + 3 ] = 0x00;
49 pixelOffset += ( imageHeight - 1 ) * imageWidth * bytesPerPixel;
50 pixbuffer[ pixelOffset + 3 ] = 0x00;
53 for ( unsigned int column = 0; column < imageHeight; ++column )
55 unsigned int pixelOffset = column * imageWidth * bytesPerPixel;
56 pixbuffer[ pixelOffset + 3 ] = 0x00;
57 pixelOffset += ( imageWidth -1 ) * bytesPerPixel;
58 pixbuffer[ pixelOffset + 3 ] = 0x00;
62 void AddStretchRegionsToImage( Integration::Bitmap* image, unsigned int imageWidth, unsigned int imageHeight, const Vector4& requiredStretchBorder, Pixel::Format pixelFormat )
64 PixelBuffer* pixbuffer = image->GetBuffer();
65 unsigned int bytesPerPixel = GetBytesPerPixel( pixelFormat );
67 for( unsigned int column = requiredStretchBorder.x; column < imageWidth - requiredStretchBorder.z; ++column )
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;
76 for( unsigned int row = requiredStretchBorder.y; row < imageHeight - requiredStretchBorder.w; ++row )
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;
86 void AddChildRegionsToImage( Integration::Bitmap* image, unsigned int imageWidth, unsigned int imageHeight, const Vector4& requiredChildRegion, Pixel::Format pixelFormat )
88 PixelBuffer* pixbuffer = image->GetBuffer();
89 unsigned int bytesPerPixel = GetBytesPerPixel( pixelFormat );
91 Integration::Bitmap::PackedPixelsProfile* srcProfile = image->GetPackedPixelsProfile();
92 unsigned int bufferStride = srcProfile->GetBufferStride();
94 // Add bottom child region
95 for( unsigned int column = requiredChildRegion.x; column < imageWidth - requiredChildRegion.z; ++column )
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;
105 // Add right child region
106 for ( unsigned int row = requiredChildRegion.y; row < imageHeight - requiredChildRegion.w; ++row )
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;
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 )
123 TestPlatformAbstraction& platform = application.GetPlatform();
125 Pixel::Format pixelFormat = Pixel::RGBA8888;
127 tet_infoline("Create Bitmap");
128 platform.SetClosestImageSize(Vector2( ninePatchImageWidth, ninePatchImageHeight));
129 Integration::Bitmap* bitmap = CreateBitmap( ninePatchImageWidth, ninePatchImageHeight, 0xFF, pixelFormat );
131 tet_infoline("Clear border regions");
132 InitialiseRegionsToZeroAlpha( bitmap, ninePatchImageWidth, ninePatchImageHeight, pixelFormat );
134 tet_infoline("Add Stretch regions to Bitmap");
135 AddStretchRegionsToImage( bitmap, ninePatchImageWidth, ninePatchImageHeight, requiredStretchBorder, pixelFormat );
139 tet_infoline("Add Child regions to Bitmap");
140 AddChildRegionsToImage( bitmap, ninePatchImageWidth, ninePatchImageHeight, requiredChildRegion, pixelFormat );
143 tet_infoline("Setting resource as it's loaded synchronously");
144 Integration::ResourcePointer resourcePtr(bitmap);
145 platform.SetSynchronouslyLoadedResource( resourcePtr );
147 std::string url( "blah.#.png" );
148 Image image = ResourceImage::New( url );
150 tet_infoline("Assign image to image rendering actor");
151 Actor actor = CreateRenderableActor( image );
152 Stage::GetCurrent().Add( actor );
154 tet_infoline("Downcast Image to a nine-patch image\n");
155 NinePatchImage ninePatchImage = NinePatchImage::DownCast( image );
157 DALI_TEST_EQUALS( url, ninePatchImage.GetUrl(), TEST_LOCATION );
159 return ninePatchImage;
165 int UtcDaliNinePatchImageNew(void)
167 TestApplication application;
168 tet_infoline("UtcDaliNinePatchImageNew - NinePatchImage::New(const std::string&)");
170 // invoke default handle constructor
171 NinePatchImage image;
173 DALI_TEST_CHECK( !image );
176 std::string url("blah.#.png");
177 image = NinePatchImage::New( url );
179 DALI_TEST_CHECK( image );
181 DALI_TEST_EQUALS( url, image.GetUrl(), TEST_LOCATION );
186 int UtcDaliNinePatchImageDowncast(void)
188 TestApplication application;
189 tet_infoline("UtcDaliNinePatchImageDowncast - NinePatchImage::DownCast(BaseHandle)");
191 NinePatchImage image = NinePatchImage::New( "blah.#.png" );
193 BaseHandle object( image );
195 NinePatchImage image2 = NinePatchImage::DownCast( object );
196 DALI_TEST_CHECK( image2 );
198 NinePatchImage image3 = DownCast< NinePatchImage >( object );
199 DALI_TEST_CHECK( image3 );
201 BaseHandle unInitializedObject;
202 NinePatchImage image4 = NinePatchImage::DownCast( unInitializedObject );
203 DALI_TEST_CHECK( !image4 );
205 NinePatchImage image5 = DownCast< NinePatchImage >( unInitializedObject );
206 DALI_TEST_CHECK( !image5 );
208 Image image6 = NinePatchImage::New( "blah.#.png" );
209 NinePatchImage image7 = NinePatchImage::DownCast( image6 );
210 DALI_TEST_CHECK( image7 );
214 int UtcDaliNinePatchImageCopyConstructor(void)
216 TestApplication application;
218 tet_infoline("UtcDaliNinePatchImageCopyConstructor - NinePatchImage::NinePatchImage( const NinePatchImage& )");
220 NinePatchImage image1;
221 DALI_TEST_CHECK( !image1 );
223 image1 = NinePatchImage::New( "blah.#.png" );
224 NinePatchImage image2( image1 );
226 DALI_TEST_CHECK( image2 );
227 DALI_TEST_EQUALS( image1, image2, TEST_LOCATION );
232 int UtcDaliNinePatchImageGetStrechBorders(void)
234 TestApplication application;
235 tet_infoline("UtcDaliNinePatchImageGetStrechBorders - NinePatchImage::GetStretchBorders()");
237 /* Stretch region left(2) top(2) right (2) bottom (2)
248 const unsigned int ninePatchImageHeight = 18;
249 const unsigned int ninePatchImageWidth = 28;
250 const Vector4 requiredStretchBorder( 3, 4, 5, 6 );
252 NinePatchImage ninePatchImage = CustomizeNinePatch( application, ninePatchImageWidth, ninePatchImageHeight, requiredStretchBorder );
253 DALI_TEST_CHECK( ninePatchImage );
257 tet_infoline("Get Stretch regions from NinePatch");
259 const NinePatchImage::StretchRanges& stretchPixelsX = ninePatchImage.GetStretchPixelsX();
260 const NinePatchImage::StretchRanges& stretchPixelsY = ninePatchImage.GetStretchPixelsY();
262 DALI_TEST_CHECK( stretchPixelsX.Size() == 1 );
263 DALI_TEST_CHECK( stretchPixelsY.Size() == 1 );
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;
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 );
275 Vector4 actualStretchBorders = ninePatchImage.GetStretchBorders();
276 DALI_TEST_EQUALS( actualStretchBorders, requiredStretchBorder, 0.001, TEST_LOCATION );
280 tet_infoline("Image not NinePatch");
281 test_return_value = TET_FAIL;
287 int UtcDaliNinePatchImageGetChildRectangle(void)
289 TestApplication application;
290 tet_infoline("UtcDaliNinePatchImageGetChildRectangle - NinePatchImage::GetChildRectangle()");
292 /* Child region x(2) y(2) width (4) height (4)
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 );
309 NinePatchImage ninePatchImage = CustomizeNinePatch( application,ninePatchImageWidth, ninePatchImageHeight, requiredStretchBorder, true, requiredChildRegion );
310 DALI_TEST_CHECK( ninePatchImage );
312 if ( ninePatchImage )
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 );
322 tet_infoline("Image not NinePatch");
323 test_return_value = TET_FAIL;
329 int UtcDaliNinePatchImageCreateCroppedBufferImage(void)
331 TestApplication application;
332 tet_infoline("UtcDaliNinePatchImageCreateCroppedBufferImage - NinePatchImage::CreateCroppedBufferImage()");
334 const unsigned int ninePatchImageHeight = 8;
335 const unsigned int ninePatchImageWidth = 8;
336 const Vector4 requiredStretchBorder( 1, 1, 1, 1 );
338 NinePatchImage ninePatchImage = CustomizeNinePatch( application, ninePatchImageWidth, ninePatchImageHeight, requiredStretchBorder );
339 DALI_TEST_CHECK( ninePatchImage );
341 if ( ninePatchImage )
343 BufferImage newImage = ninePatchImage.CreateCroppedBufferImage();
344 DALI_TEST_CHECK( newImage );
346 DALI_TEST_EQUALS( newImage.GetPixelFormat(), Pixel::RGBA8888, TEST_LOCATION );
348 DALI_TEST_EQUALS( newImage.GetBufferSize(), 144u/* 36*4 */, TEST_LOCATION );
352 tet_infoline("Image not NinePatch");
353 test_return_value = TET_FAIL;
359 int UtcDaliNinePatchImageIsNinePatchUrl(void)
361 TestApplication application;
362 tet_infoline("UtcDaliNinePatchImageIsNinePatchUrl - NinePatchImage::IsNinePatchUrl(const std::string&)");
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" ) );