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