Implemented n-patch rendering for NPatchRenderer. 38/48538/12
authorChu Hoang <c.hoang@samsung.com>
Tue, 22 Sep 2015 13:21:17 +0000 (14:21 +0100)
committerChu Hoang <c.hoang@samsung.com>
Tue, 13 Oct 2015 12:47:05 +0000 (13:47 +0100)
Change-Id: Ic7304dc47483cc228dce9e715be9bc0bb46a081e

automated-tests/src/dali-toolkit/utc-Dali-RendererFactory.cpp
dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.cpp
dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.h

index a570b72..391bc74 100644 (file)
@@ -27,6 +27,8 @@ using namespace Dali::Toolkit;
 
 namespace
 {
+typedef NinePatchImage::StretchRanges StretchRanges;
+
 const char* TEST_IMAGE_FILE_NAME =  "gallery_image_01.jpg";
 const char* TEST_NPATCH_FILE_NAME =  "gallery_image_01.9.jpg";
 
@@ -63,27 +65,38 @@ void InitialiseRegionsToZeroAlpha( Integration::Bitmap* image, unsigned int imag
   }
 }
 
-void AddStretchRegionsToImage( Integration::Bitmap* image, unsigned int imageWidth, unsigned int imageHeight, const Vector4& requiredStretchBorder, Pixel::Format pixelFormat )
+void AddStretchRegionsToImage( Integration::Bitmap* image, unsigned int imageWidth, unsigned int imageHeight, const StretchRanges& stretchRangesX, const StretchRanges& stretchRangesY, Pixel::Format pixelFormat )
 {
   PixelBuffer* pixbuffer = image->GetBuffer();
   unsigned int bytesPerPixel = GetBytesPerPixel( pixelFormat );
 
-  for( unsigned int column = requiredStretchBorder.x; column < imageWidth - requiredStretchBorder.z; ++column )
+  for(StretchRanges::ConstIterator it = stretchRangesX.Begin(); it != stretchRangesX.End(); ++it)
   {
-    unsigned int pixelOffset = column * bytesPerPixel;
-    pixbuffer[ pixelOffset ] = 0x00;
-    pixbuffer[ pixelOffset + 1 ] = 0x00;
-    pixbuffer[ pixelOffset + 2 ] = 0x00;
-    pixbuffer[ pixelOffset + 3 ] = 0xFF;
+    const Uint16Pair& range = *it;
+    //since the stretch range is in the cropped image space, we need to offset by 1 to get it to the uncropped image space
+    for( unsigned int column = range.GetX() + 1u; column < range.GetY() + 1u; ++column )
+    {
+      unsigned int pixelOffset = column * bytesPerPixel;
+      pixbuffer[ pixelOffset ] = 0x00;
+      pixbuffer[ pixelOffset + 1 ] = 0x00;
+      pixbuffer[ pixelOffset + 2 ] = 0x00;
+      pixbuffer[ pixelOffset + 3 ] = 0xFF;
+    }
   }
 
-  for( unsigned int row = requiredStretchBorder.y; row < imageHeight - requiredStretchBorder.w; ++row )
+
+  for(StretchRanges::ConstIterator it = stretchRangesY.Begin(); it != stretchRangesY.End(); ++it)
   {
-    unsigned int pixelOffset = row * imageWidth * bytesPerPixel;
-    pixbuffer[ pixelOffset ] = 0x00;
-    pixbuffer[ pixelOffset + 1 ] = 0x00;
-    pixbuffer[ pixelOffset + 2 ] = 0x00;
-    pixbuffer[ pixelOffset + 3 ] = 0xFF;
+    const Uint16Pair& range = *it;
+    //since the stretch range is in the cropped image space, we need to offset by 1 to get it to the uncropped image space
+    for( unsigned int row = range.GetX() + 1u; row < range.GetY() + 1u; ++row )
+    {
+      unsigned int pixelOffset = row * imageWidth * bytesPerPixel;
+      pixbuffer[ pixelOffset ] = 0x00;
+      pixbuffer[ pixelOffset + 1 ] = 0x00;
+      pixbuffer[ pixelOffset + 2 ] = 0x00;
+      pixbuffer[ pixelOffset + 3 ] = 0xFF;
+    }
   }
 }
 
@@ -120,7 +133,8 @@ void AddChildRegionsToImage( Integration::Bitmap* image, unsigned int imageWidth
 Integration::ResourcePointer CustomizeNinePatch( TestApplication& application,
                                                  unsigned int ninePatchImageWidth,
                                                  unsigned int ninePatchImageHeight,
-                                                 const Vector4& requiredStretchBorder,
+                                                 const StretchRanges& stretchRangesX,
+                                                 const StretchRanges& stretchRangesY,
                                                  bool addChildRegion = false,
                                                  Vector4 requiredChildRegion = Vector4::ZERO )
 {
@@ -136,7 +150,7 @@ Integration::ResourcePointer CustomizeNinePatch( TestApplication& application,
   InitialiseRegionsToZeroAlpha( bitmap, ninePatchImageWidth, ninePatchImageHeight, pixelFormat );
 
   tet_infoline("Add Stretch regions to Bitmap");
-  AddStretchRegionsToImage( bitmap, ninePatchImageWidth, ninePatchImageHeight, requiredStretchBorder, pixelFormat );
+  AddStretchRegionsToImage( bitmap, ninePatchImageWidth, ninePatchImageHeight, stretchRangesX, stretchRangesY, pixelFormat );
 
   if( addChildRegion )
   {
@@ -151,6 +165,40 @@ Integration::ResourcePointer CustomizeNinePatch( TestApplication& application,
   return resourcePtr;
 }
 
+void TestControlRendererRender( ToolkitTestApplication& application, Actor& actor, ControlRenderer& controlRenderer, Integration::ResourcePointer resourcePtr = Integration::ResourcePointer(), std::size_t expectedSamplers = 0)
+{
+  actor.SetSize( 200.f, 200.f );
+  Stage::GetCurrent().Add( actor );
+  controlRenderer.SetSize( Vector2(200.f, 200.f) );
+  controlRenderer.SetOnStage( actor );
+
+  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+  DALI_TEST_CHECK( actor.GetRendererAt(0u).GetMaterial().GetNumberOfSamplers() == expectedSamplers );
+
+  application.SendNotification();
+  application.Render();
+
+  if( resourcePtr )
+  {
+    Integration::ResourceRequest* request = application.GetPlatform().GetRequest();
+    if(request)
+    {
+      application.GetPlatform().SetResourceLoaded(request->GetId(), request->GetType()->id, resourcePtr );
+    }
+  }
+
+  application.Render();
+  application.SendNotification();
+
+  if( resourcePtr )
+  {
+    DALI_TEST_CHECK(application.GetPlatform().WasCalled(TestPlatformAbstraction::LoadResourceFunc));
+  }
+
+  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+
+}
+
 } // namespace
 
 
@@ -234,19 +282,10 @@ int UtcDaliRendererFactoryGetColorRenderer1(void)
   DALI_TEST_CHECK( controlRenderer );
 
   Actor actor = Actor::New();
-  actor.SetSize(200.f, 200.f);
-  Stage::GetCurrent().Add( actor );
-  controlRenderer.SetSize(Vector2(200.f, 200.f));
-  controlRenderer.SetOnStage( actor );
-
-  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
-
-  TestGlAbstraction& gl = application.GetGlAbstraction();
-
-  application.SendNotification();
-  application.Render(0);
+  TestControlRendererRender( application, actor, controlRenderer );
 
   Vector4 actualValue(Vector4::ZERO);
+  TestGlAbstraction& gl = application.GetGlAbstraction();
   DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uBlendColor", actualValue ) );
   DALI_TEST_EQUALS( actualValue, testColor, TEST_LOCATION );
 
@@ -266,19 +305,10 @@ int UtcDaliRendererFactoryGetColorRenderer2(void)
   DALI_TEST_CHECK( controlRenderer );
 
   Actor actor = Actor::New();
-  actor.SetSize(200.f, 200.f);
-  Stage::GetCurrent().Add( actor );
-  controlRenderer.SetSize(Vector2(200.f, 200.f));
-  controlRenderer.SetOnStage( actor );
-
-  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
-
-  TestGlAbstraction& gl = application.GetGlAbstraction();
-
-  application.SendNotification();
-  application.Render(0);
+  TestControlRendererRender( application, actor, controlRenderer );
 
   Vector4 actualValue(Vector4::ZERO);
+  TestGlAbstraction& gl = application.GetGlAbstraction();
   DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uBlendColor", actualValue ) );
   DALI_TEST_EQUALS( actualValue, testColor, TEST_LOCATION );
 
@@ -402,20 +432,9 @@ int UtcDaliRendererFactoryGetLinearGradientRenderer(void)
   ControlRenderer controlRenderer = factory.GetControlRenderer(propertyMap);
   DALI_TEST_CHECK( controlRenderer );
 
-  Actor actor = Actor::New();
-  Vector2 size(200.f, 200.f);
-  actor.SetSize(size);
-  Stage::GetCurrent().Add( actor );
-  controlRenderer.SetOnStage( actor );
-  controlRenderer.SetSize(size);
-
-  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
-
   // A lookup texture is generated and pass to shader as sampler
-  DALI_TEST_CHECK( actor.GetRendererAt(0u).GetMaterial().GetNumberOfSamplers() == 1u );
-
-  application.SendNotification();
-  application.Render(0);
+  Actor actor = Actor::New();
+  TestControlRendererRender( application, actor, controlRenderer, Integration::ResourcePointer(), 1u );
 
   controlRenderer.SetOffStage( actor );
   DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
@@ -453,26 +472,15 @@ int UtcDaliRendererFactoryGetRadialGradientRenderer(void)
   ControlRenderer controlRenderer = factory.GetControlRenderer(propertyMap);
   DALI_TEST_CHECK( controlRenderer );
 
-  Actor actor = Actor::New();
-  Vector2 size(200.f, 200.f);
-  actor.SetSize(size);
-  Stage::GetCurrent().Add( actor );
-  controlRenderer.SetSize(size);
-  controlRenderer.SetOnStage( actor );
-
-  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
-
   // A lookup texture is generated and pass to shader as sampler
-  DALI_TEST_CHECK( actor.GetRendererAt(0u).GetMaterial().GetNumberOfSamplers() == 1u );
-
-  TestGlAbstraction& gl = application.GetGlAbstraction();
-  application.SendNotification();
-  application.Render(0);
+  Actor actor = Actor::New();
+  TestControlRendererRender( application, actor, controlRenderer, Integration::ResourcePointer(), 1u );
 
   Matrix3 alignMatrix( radius, 0.f, 0.f, 0.f, radius, 0.f, center.x, center.y, 1.f );
   alignMatrix.Invert();
 
   Matrix3 actualValue( Matrix3::IDENTITY );
+  TestGlAbstraction& gl = application.GetGlAbstraction();
   DALI_TEST_CHECK( gl.GetUniformValue<Matrix3>( "uAlignmentMatrix", actualValue ) );
   DALI_TEST_EQUALS( actualValue, alignMatrix, Math::MACHINE_EPSILON_100, TEST_LOCATION );
 
@@ -495,31 +503,9 @@ int UtcDaliRendererFactoryGetImageRenderer1(void)
   DALI_TEST_CHECK( controlRenderer );
 
   Actor actor = Actor::New();
-  actor.SetSize( 200.f, 200.f );
-  Stage::GetCurrent().Add( actor );
-  controlRenderer.SetSize( Vector2(200.f, 200.f) );
-  controlRenderer.SetOnStage( actor );
-
-  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
-  DALI_TEST_CHECK( actor.GetRendererAt(0u).GetMaterial().GetNumberOfSamplers() == 1u );
+  TestControlRendererRender( application, actor, controlRenderer, Integration::ResourcePointer(Integration::Bitmap::New(Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::OWNED_DISCARD)), 1u );
 
   TestGlAbstraction& gl = application.GetGlAbstraction();
-  application.SendNotification();
-  application.Render();
-
-  Integration::ResourceRequest* request = application.GetPlatform().GetRequest();
-  if(request)
-  {
-    application.GetPlatform().SetResourceLoaded(request->GetId(), request->GetType()->id, Integration::ResourcePointer(Integration::Bitmap::New(Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::OWNED_DISCARD)));
-  }
-
-  application.Render();
-  application.SendNotification();
-
-  DALI_TEST_CHECK(application.GetPlatform().WasCalled(TestPlatformAbstraction::LoadResourceFunc));
-
-  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
-
   int textureUnit = -1;
   DALI_TEST_CHECK( gl.GetUniformValue< int >( "sTexture", textureUnit ) );
   DALI_TEST_EQUALS( textureUnit, 0, TEST_LOCATION );
@@ -542,29 +528,9 @@ int UtcDaliRendererFactoryGetImageRenderer2(void)
   ControlRenderer controlRenderer = factory.GetControlRenderer( image );
 
   Actor actor = Actor::New();
-  actor.SetSize( 200.f, 200.f );
-  Stage::GetCurrent().Add( actor );
-  controlRenderer.SetSize( Vector2(200.f, 200.f) );
-  controlRenderer.SetOnStage( actor );
-
-  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
-  DALI_TEST_CHECK( actor.GetRendererAt(0u).GetMaterial().GetNumberOfSamplers() == 1u );
+  TestControlRendererRender( application, actor, controlRenderer, Integration::ResourcePointer(Integration::Bitmap::New(Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::OWNED_DISCARD)), 1u );
 
   TestGlAbstraction& gl = application.GetGlAbstraction();
-  application.SendNotification();
-  application.Render();
-
-  Integration::ResourceRequest* request = application.GetPlatform().GetRequest();
-  if(request)
-  {
-    application.GetPlatform().SetResourceLoaded(request->GetId(), request->GetType()->id, Integration::ResourcePointer(Integration::Bitmap::New(Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::OWNED_DISCARD)));
-  }
-
-  application.Render();
-  application.SendNotification();
-
-  DALI_TEST_CHECK(application.GetPlatform().WasCalled(TestPlatformAbstraction::LoadResourceFunc));
-
   int textureUnit = -1;
   DALI_TEST_CHECK( gl.GetUniformValue< int >( "sTexture", textureUnit ) );
   DALI_TEST_EQUALS( textureUnit, 0, TEST_LOCATION );
@@ -575,99 +541,173 @@ int UtcDaliRendererFactoryGetImageRenderer2(void)
 int UtcDaliRendererFactoryGetNPatchRenderer1(void)
 {
   ToolkitTestApplication application;
-  tet_infoline( "UtcDaliRendererFactoryGetNPatchRenderer1: Request n-patch renderer with a Property::Map" );
+  tet_infoline( "UtcDaliRendererFactoryGetNPatchRenderer1: Request 9-patch renderer with a Property::Map" );
 
   RendererFactory factory = RendererFactory::Get();
   DALI_TEST_CHECK( factory );
 
   const unsigned int ninePatchImageHeight = 18;
   const unsigned int ninePatchImageWidth = 28;
-  const Vector4 requiredStretchBorder( 3, 4, 5, 6 );
-  Integration::ResourcePointer ninePatchResource = CustomizeNinePatch( application, ninePatchImageWidth, ninePatchImageHeight, requiredStretchBorder );
+  StretchRanges stretchRangesX;
+  stretchRangesX.PushBack( Uint16Pair( 2, 3 ) );
+  StretchRanges stretchRangesY;
+  stretchRangesY.PushBack( Uint16Pair( 4, 5 ) );
+  Integration::ResourcePointer ninePatchResource = CustomizeNinePatch( application, ninePatchImageWidth, ninePatchImageHeight, stretchRangesX, stretchRangesY );
 
   Property::Map propertyMap;
   propertyMap.Insert( "renderer-type", "n-patch-renderer" );
   propertyMap.Insert( "image-url", TEST_NPATCH_FILE_NAME );
+  {
+    tet_infoline( "whole grid" );
+    ControlRenderer controlRenderer = factory.GetControlRenderer( propertyMap );
+    DALI_TEST_CHECK( controlRenderer );
 
-  ControlRenderer controlRenderer = factory.GetControlRenderer( propertyMap );
-  DALI_TEST_CHECK( controlRenderer );
+    Actor actor = Actor::New();
+    TestControlRendererRender( application, actor, controlRenderer, ninePatchResource, 1u );
 
-  Actor actor = Actor::New();
-  actor.SetSize( 200.f, 200.f );
-  Stage::GetCurrent().Add( actor );
-  controlRenderer.SetSize( Vector2(200.f, 200.f) );
-  controlRenderer.SetOnStage( actor );
+    TestGlAbstraction& gl = application.GetGlAbstraction();
+    int textureUnit = -1;
+    DALI_TEST_CHECK( gl.GetUniformValue< int >( "sTexture", textureUnit ) );
+    DALI_TEST_EQUALS( textureUnit, 0, TEST_LOCATION );
+  }
 
-  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
-  DALI_TEST_CHECK( actor.GetRendererAt(0u).GetMaterial().GetNumberOfSamplers() == 1u );
+  propertyMap.Insert( "border-only", true );
+  {
+    tet_infoline( "border only" );
+    ControlRenderer controlRenderer = factory.GetControlRenderer( propertyMap );
+    DALI_TEST_CHECK( controlRenderer );
 
-  TestGlAbstraction& gl = application.GetGlAbstraction();
-  application.SendNotification();
-  application.Render();
+    Actor actor = Actor::New();
+    TestControlRendererRender( application, actor, controlRenderer, ninePatchResource, 1u );
 
-  Integration::ResourceRequest* request = application.GetPlatform().GetRequest();
-  if(request)
-  {
-    application.GetPlatform().SetResourceLoaded(request->GetId(), request->GetType()->id, ninePatchResource );
+    TestGlAbstraction& gl = application.GetGlAbstraction();
+    int textureUnit = -1;
+    DALI_TEST_CHECK( gl.GetUniformValue< int >( "sTexture", textureUnit ) );
+    DALI_TEST_EQUALS( textureUnit, 0, TEST_LOCATION );
   }
 
-  application.Render();
-  application.SendNotification();
+  END_TEST;
+}
 
-  DALI_TEST_CHECK(application.GetPlatform().WasCalled(TestPlatformAbstraction::LoadResourceFunc));
+int UtcDaliRendererFactoryGetNPatchRenderer2(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliRendererFactoryGetNPatchRenderer2: Request n-patch renderer with a Property::Map" );
 
-  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+  RendererFactory factory = RendererFactory::Get();
+  DALI_TEST_CHECK( factory );
 
-  int textureUnit = -1;
-  DALI_TEST_CHECK( gl.GetUniformValue< int >( "sTexture", textureUnit ) );
-  DALI_TEST_EQUALS( textureUnit, 0, TEST_LOCATION );
+  const unsigned int ninePatchImageWidth = 18;
+  const unsigned int ninePatchImageHeight = 28;
+  StretchRanges stretchRangesX;
+  stretchRangesX.PushBack( Uint16Pair( 2, 3 ) );
+  stretchRangesX.PushBack( Uint16Pair( 5, 7 ) );
+  stretchRangesX.PushBack( Uint16Pair( 12, 15 ) );
+  StretchRanges stretchRangesY;
+  stretchRangesY.PushBack( Uint16Pair( 4, 5 ) );
+  stretchRangesY.PushBack( Uint16Pair( 8, 12 ) );
+  stretchRangesY.PushBack( Uint16Pair( 15, 16 ) );
+  stretchRangesY.PushBack( Uint16Pair( 25, 27 ) );
+  Integration::ResourcePointer ninePatchResource = CustomizeNinePatch( application, ninePatchImageWidth, ninePatchImageHeight, stretchRangesX, stretchRangesY );
 
-  controlRenderer.SetOffStage( actor );
-  DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
+  Property::Map propertyMap;
+  propertyMap.Insert( "renderer-type", "n-patch-renderer" );
+  propertyMap.Insert( "image-url", TEST_NPATCH_FILE_NAME );
+  {
+    ControlRenderer controlRenderer = factory.GetControlRenderer( propertyMap );
+    DALI_TEST_CHECK( controlRenderer );
+
+    Actor actor = Actor::New();
+    TestControlRendererRender( application, actor, controlRenderer, ninePatchResource, 1u );
+
+    TestGlAbstraction& gl = application.GetGlAbstraction();
+    int textureUnit = -1;
+    DALI_TEST_CHECK( gl.GetUniformValue< int >( "sTexture", textureUnit ) );
+    DALI_TEST_EQUALS( textureUnit, 0, TEST_LOCATION );
+
+    controlRenderer.SetOffStage( actor );
+    DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
+  }
+
+  propertyMap.Insert( "border-only", true );
+  {
+    tet_infoline( "border only" );
+    ControlRenderer controlRenderer = factory.GetControlRenderer( propertyMap );
+    DALI_TEST_CHECK( controlRenderer );
+
+    Actor actor = Actor::New();
+    TestControlRendererRender( application, actor, controlRenderer, ninePatchResource, 1u );
+
+    TestGlAbstraction& gl = application.GetGlAbstraction();
+    int textureUnit = -1;
+    DALI_TEST_CHECK( gl.GetUniformValue< int >( "sTexture", textureUnit ) );
+    DALI_TEST_EQUALS( textureUnit, 0, TEST_LOCATION );
+
+    controlRenderer.SetOffStage( actor );
+    DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
+  }
 
   END_TEST;
 }
 
-int UtcDaliRendererFactoryGetNPatchRenderer2(void)
+int UtcDaliRendererFactoryGetNPatchRenderer3(void)
 {
   ToolkitTestApplication application;
-  tet_infoline( "UtcDaliRendererFactoryGetNPatchRenderer2: Request n-patch renderer with an image url" );
+  tet_infoline( "UtcDaliRendererFactoryGetNPatchRenderer3: Request 9-patch renderer with an image url" );
 
   RendererFactory factory = RendererFactory::Get();
   DALI_TEST_CHECK( factory );
 
   const unsigned int ninePatchImageHeight = 18;
   const unsigned int ninePatchImageWidth = 28;
-  const Vector4 requiredStretchBorder( 3, 4, 5, 6 );
-  Integration::ResourcePointer ninePatchResource = CustomizeNinePatch( application, ninePatchImageWidth, ninePatchImageHeight, requiredStretchBorder );
+  StretchRanges stretchRangesX;
+  stretchRangesX.PushBack( Uint16Pair( 2, 3 ) );
+  StretchRanges stretchRangesY;
+  stretchRangesY.PushBack( Uint16Pair( 4, 5 ) );
+  Integration::ResourcePointer ninePatchResource = CustomizeNinePatch( application, ninePatchImageWidth, ninePatchImageHeight, stretchRangesX, stretchRangesY );
 
   ControlRenderer controlRenderer = factory.GetControlRenderer( TEST_NPATCH_FILE_NAME );
   DALI_TEST_CHECK( controlRenderer );
 
   Actor actor = Actor::New();
-  actor.SetSize( 200.f, 200.f );
-  Stage::GetCurrent().Add( actor );
-  controlRenderer.SetSize( Vector2(200.f, 200.f) );
-  controlRenderer.SetOnStage( actor );
-
-  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
-  DALI_TEST_CHECK( actor.GetRendererAt(0u).GetMaterial().GetNumberOfSamplers() == 1u );
+  TestControlRendererRender( application, actor, controlRenderer, ninePatchResource, 1u );
 
   TestGlAbstraction& gl = application.GetGlAbstraction();
-  application.SendNotification();
-  application.Render();
+  int textureUnit = -1;
+  DALI_TEST_CHECK( gl.GetUniformValue< int >( "sTexture", textureUnit ) );
+  DALI_TEST_EQUALS( textureUnit, 0, TEST_LOCATION );
 
-  Integration::ResourceRequest* request = application.GetPlatform().GetRequest();
-  if(request)
-  {
-    application.GetPlatform().SetResourceLoaded(request->GetId(), request->GetType()->id, ninePatchResource );
-  }
+  END_TEST;
+}
 
-  application.Render();
-  application.SendNotification();
+int UtcDaliRendererFactoryGetNPatchRenderer4(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliRendererFactoryGetNPatchRenderer4: Request n-patch renderer with an image url" );
+
+  RendererFactory factory = RendererFactory::Get();
+  DALI_TEST_CHECK( factory );
+
+  const unsigned int ninePatchImageHeight = 18;
+  const unsigned int ninePatchImageWidth = 28;
+  StretchRanges stretchRangesX;
+  stretchRangesX.PushBack( Uint16Pair( 2, 3 ) );
+  stretchRangesX.PushBack( Uint16Pair( 5, 7 ) );
+  stretchRangesX.PushBack( Uint16Pair( 12, 15 ) );
+  StretchRanges stretchRangesY;
+  stretchRangesY.PushBack( Uint16Pair( 4, 5 ) );
+  stretchRangesY.PushBack( Uint16Pair( 8, 12 ) );
+  stretchRangesY.PushBack( Uint16Pair( 15, 16 ) );
+  stretchRangesY.PushBack( Uint16Pair( 25, 27 ) );
+  Integration::ResourcePointer ninePatchResource = CustomizeNinePatch( application, ninePatchImageWidth, ninePatchImageHeight, stretchRangesX, stretchRangesY );
+
+  ControlRenderer controlRenderer = factory.GetControlRenderer( TEST_NPATCH_FILE_NAME );
+  DALI_TEST_CHECK( controlRenderer );
 
-  DALI_TEST_CHECK(application.GetPlatform().WasCalled(TestPlatformAbstraction::LoadResourceFunc));
+  Actor actor = Actor::New();
+  TestControlRendererRender( application, actor, controlRenderer, ninePatchResource, 1u );
 
+  TestGlAbstraction& gl = application.GetGlAbstraction();
   int textureUnit = -1;
   DALI_TEST_CHECK( gl.GetUniformValue< int >( "sTexture", textureUnit ) );
   DALI_TEST_EQUALS( textureUnit, 0, TEST_LOCATION );
@@ -689,18 +729,9 @@ int UtcDaliRendererFactoryGetNPatchRendererN1(void)
   DALI_TEST_CHECK( controlRenderer );
 
   Actor actor = Actor::New();
-  actor.SetSize( 200.f, 200.f );
-  Stage::GetCurrent().Add( actor );
-  controlRenderer.SetSize( Vector2(200.f, 200.f) );
-  controlRenderer.SetOnStage( actor );
-
-  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
-  DALI_TEST_CHECK( actor.GetRendererAt(0u).GetMaterial().GetNumberOfSamplers() == 1u );
+  TestControlRendererRender( application, actor, controlRenderer, Integration::ResourcePointer(), 1u );
 
   TestGlAbstraction& gl = application.GetGlAbstraction();
-  application.SendNotification();
-  application.Render();
-
   int textureUnit = -1;
   DALI_TEST_CHECK( gl.GetUniformValue< int >( "sTexture", textureUnit ) );
   DALI_TEST_EQUALS( textureUnit, 0, TEST_LOCATION );
@@ -726,18 +757,9 @@ int UtcDaliRendererFactoryGetNPatchRendererN2(void)
   DALI_TEST_CHECK( controlRenderer );
 
   Actor actor = Actor::New();
-  actor.SetSize( 200.f, 200.f );
-  Stage::GetCurrent().Add( actor );
-  controlRenderer.SetSize( Vector2(200.f, 200.f) );
-  controlRenderer.SetOnStage( actor );
-
-  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
-  DALI_TEST_CHECK( actor.GetRendererAt(0u).GetMaterial().GetNumberOfSamplers() == 1u );
+  TestControlRendererRender( application, actor, controlRenderer, Integration::ResourcePointer(), 1u );
 
   TestGlAbstraction& gl = application.GetGlAbstraction();
-  application.SendNotification();
-  application.Render();
-
   int textureUnit = -1;
   DALI_TEST_CHECK( gl.GetUniformValue< int >( "sTexture", textureUnit ) );
   DALI_TEST_EQUALS( textureUnit, 0, TEST_LOCATION );
@@ -750,23 +772,17 @@ int UtcDaliRendererFactoryResetRenderer1(void)
   ToolkitTestApplication application;
   tet_infoline( "UtcDaliRendererFactoryResetRenderer1" );
 
-  Actor actor = Actor::New();
-  actor.SetSize(200.f, 200.f);
-  Stage::GetCurrent().Add( actor );
-
   RendererFactory factory = RendererFactory::Get();
   DALI_TEST_CHECK( factory );
 
   ControlRenderer controlRenderer = factory.GetControlRenderer( Color::RED );
   DALI_TEST_CHECK( controlRenderer );
-  controlRenderer.SetSize(Vector2(200.f, 200.f));
-  controlRenderer.SetOnStage( actor );
-  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
 
-  TestGlAbstraction& gl = application.GetGlAbstraction();
-  application.SendNotification();
-  application.Render(0);
+  Actor actor = Actor::New();
+  TestControlRendererRender( application, actor, controlRenderer );
+
   Vector4 actualValue(Vector4::ZERO);
+  TestGlAbstraction& gl = application.GetGlAbstraction();
   DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uBlendColor", actualValue ) );
   DALI_TEST_EQUALS( actualValue, Color::RED, TEST_LOCATION );
 
index 63e2f5d..cd23466 100644 (file)
@@ -49,6 +49,32 @@ const char * const BORDER_ONLY("border-only");
 
 std::string TEXTURE_UNIFORM_NAME = "sTexture";
 
+const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
+  attribute mediump vec2 aPosition;\n
+  varying mediump vec2 vTexCoord;\n
+  uniform mediump mat4 uMvpMatrix;\n
+  uniform mediump vec3 uSize;\n
+  uniform mediump vec2 uNinePatchFactorsX[ FACTOR_SIZE_X ];\n
+  uniform mediump vec2 uNinePatchFactorsY[ FACTOR_SIZE_Y ];\n
+  \n
+  void main()\n
+  {\n
+    mediump vec2 fixedFactor  = vec2( uNinePatchFactorsX[ int( ( aPosition.x + 1.0 ) * 0.5 ) ].x, uNinePatchFactorsY[ int( ( aPosition.y + 1.0 ) * 0.5 ) ].x );\n
+    mediump vec2 stretch      = vec2( uNinePatchFactorsX[ int( ( aPosition.x       ) * 0.5 ) ].y, uNinePatchFactorsY[ int( ( aPosition.y       ) * 0.5 ) ].y );\n
+    \n
+    mediump vec2 fixedTotal   = vec2( uNinePatchFactorsX[ FACTOR_SIZE_X - 1 ].x, uNinePatchFactorsY[ FACTOR_SIZE_Y - 1 ].x );\n
+    mediump vec2 stretchTotal = vec2( uNinePatchFactorsX[ FACTOR_SIZE_X - 1 ].y, uNinePatchFactorsY[ FACTOR_SIZE_Y - 1 ].y );\n
+    \n
+    mediump vec4 vertexPosition = vec4( ( fixedFactor + ( uSize.xy - fixedTotal ) * stretch / stretchTotal ), 0.0, 1.0 );\n
+    vertexPosition.xy -= uSize.xy * vec2( 0.5, 0.5 );\n
+    vertexPosition = uMvpMatrix * vertexPosition;\n
+    \n
+    vTexCoord = ( fixedFactor + stretch ) / ( fixedTotal + stretchTotal );\n
+    \n
+    gl_Position = vertexPosition;\n
+  }\n
+);
+
 const char* VERTEX_SHADER_3X3 = DALI_COMPOSE_SHADER(
     attribute mediump vec2 aPosition;\n
     varying mediump vec2 vTexCoord;\n
@@ -146,6 +172,37 @@ void AddVertex( Vector< Vector2 >& vertices, unsigned int x, unsigned int y )
   vertices.PushBack( Vector2( x, y ) );
 }
 
+void RegisterStretchProperties( Sampler& sampler, const char * uniformName, const NinePatchImage::StretchRanges& stretchPixels, uint16_t imageExtent)
+{
+  uint16_t prevEnd = 0;
+  uint16_t prevFix = 0;
+  uint16_t prevStretch = 0;
+  unsigned int i = 1;
+  for( NinePatchImage::StretchRanges::ConstIterator it = stretchPixels.Begin(); it != stretchPixels.End(); ++it, ++i )
+  {
+    uint16_t start = it->GetX();
+    uint16_t end = it->GetY();
+
+    uint16_t fix = prevFix + start - prevEnd;
+    uint16_t stretch = prevStretch + end - start;
+
+    std::stringstream uniform;
+    uniform << uniformName << "[" << i << "]";
+    sampler.RegisterProperty( uniform.str(), Vector2( fix, stretch ) );
+
+    prevEnd = end;
+    prevFix = fix;
+    prevStretch = stretch;
+  }
+
+  {
+    prevFix += imageExtent - prevEnd;
+    std::stringstream uniform;
+    uniform << uniformName << "[" << i << "]";
+    sampler.RegisterProperty( uniform.str(), Vector2( prevFix, prevStretch ) );
+  }
+}
+
 } //unnamed namespace
 
 /////////////////NPatchRenderer////////////////
@@ -218,30 +275,51 @@ void NPatchRenderer::SetOffset( const Vector2& offset )
 void NPatchRenderer::InitializeRenderer( Renderer& renderer )
 {
   Geometry geometry;
-  if( !mBorderOnly )
+  Shader shader;
+  if( mStretchPixelsX.Size() == 1 && mStretchPixelsY.Size() == 1 )
   {
-    geometry = mFactoryCache.GetGeometry( RendererFactoryCache::NINE_PATCH_GEOMETRY );
-    if( !geometry )
+    if( !mBorderOnly )
     {
-      geometry = CreateGeometry( Uint16Pair( 3, 3 ) );
-      mFactoryCache.SaveGeometry( RendererFactoryCache::NINE_PATCH_GEOMETRY, geometry );
+      geometry = mFactoryCache.GetGeometry( RendererFactoryCache::NINE_PATCH_GEOMETRY );
+      if( !geometry )
+      {
+        geometry = CreateGeometry( Uint16Pair( 3, 3 ) );
+        mFactoryCache.SaveGeometry( RendererFactoryCache::NINE_PATCH_GEOMETRY, geometry );
+      }
     }
-  }
-  else
-  {
-    geometry = mFactoryCache.GetGeometry( RendererFactoryCache::NINE_PATCH_BORDER_GEOMETRY );
-    if( !geometry )
+    else
+    {
+      geometry = mFactoryCache.GetGeometry( RendererFactoryCache::NINE_PATCH_BORDER_GEOMETRY );
+      if( !geometry )
+      {
+        geometry = CreateGeometryBorder( Uint16Pair( 3, 3 ) );
+        mFactoryCache.SaveGeometry( RendererFactoryCache::NINE_PATCH_BORDER_GEOMETRY, geometry );
+      }
+    }
+
+    shader = mFactoryCache.GetShader( RendererFactoryCache::NINE_PATCH_SHADER );
+    if( !shader )
     {
-      geometry = CreateGeometryBorder( Uint16Pair( 3, 3 ) );
-      mFactoryCache.SaveGeometry( RendererFactoryCache::NINE_PATCH_BORDER_GEOMETRY, geometry );
+      shader = Shader::New( VERTEX_SHADER_3X3, FRAGMENT_SHADER );
+      mFactoryCache.SaveShader( RendererFactoryCache::NINE_PATCH_SHADER, shader );
     }
   }
+  else if( mStretchPixelsX.Size() > 0 || mStretchPixelsY.Size() > 0)
+  {
+    Uint16Pair gridSize( 2 * mStretchPixelsX.Size() + 1,  2 * mStretchPixelsY.Size() + 1 );
+    geometry = !mBorderOnly ? CreateGeometry( gridSize ) : CreateGeometryBorder( gridSize );
+
+    std::stringstream vertexShader;
+    vertexShader << "#define FACTOR_SIZE_X " << mStretchPixelsX.Size() + 2 << "\n"
+                 << "#define FACTOR_SIZE_Y " << mStretchPixelsY.Size() + 2 << "\n"
+                 << VERTEX_SHADER;
 
-  Shader shader = mFactoryCache.GetShader( RendererFactoryCache::NINE_PATCH_SHADER );
-  if( !shader )
+    shader = Shader::New( vertexShader.str(), FRAGMENT_SHADER );
+  }
+  else
   {
-    shader = Shader::New( VERTEX_SHADER_3X3, FRAGMENT_SHADER );
-    mFactoryCache.SaveShader( RendererFactoryCache::NINE_PATCH_SHADER, shader );
+    DALI_LOG_ERROR("The 9 patch image '%s' doesn't have any valid stretch borders and so is not a valid 9 patch image\n", mImageUrl.c_str() );
+    CreateErrorImage();
   }
 
   if( !renderer )
@@ -273,6 +351,8 @@ void NPatchRenderer::DoSetOnStage( Actor& actor )
     {
       InitialiseFromImage( mImage );
     }
+
+    InitializeRenderer( mImpl->mRenderer );
   }
 
   if( mCroppedImage )
@@ -374,6 +454,7 @@ void NPatchRenderer::CreateErrorImage()
   mStretchPixelsX.PushBack( Uint16Pair( 0, mImageSize.GetWidth() ) );
   mStretchPixelsY.Clear();
   mStretchPixelsY.PushBack( Uint16Pair( 0, mImageSize.GetHeight() ) );
+
 }
 
 void NPatchRenderer::ApplyImageToSampler()
@@ -397,9 +478,9 @@ void NPatchRenderer::ApplyImageToSampler()
       material.AddSampler( sampler );
     }
 
-    if( mStretchPixelsX.Size() > 0 && mStretchPixelsY.Size() > 0 )
+    if( mStretchPixelsX.Size() == 1 && mStretchPixelsY.Size() == 1 )
     {
-      //only 9 patch supported for now
+      //special case for 9 patch
       Uint16Pair stretchX = mStretchPixelsX[ 0 ];
       Uint16Pair stretchY = mStretchPixelsY[ 0 ];
 
@@ -411,6 +492,14 @@ void NPatchRenderer::ApplyImageToSampler()
       sampler.RegisterProperty( "uFixed[2]", Vector2( mImageSize.GetWidth() - stretchWidth, mImageSize.GetHeight() - stretchHeight ) );
       sampler.RegisterProperty( "uStretchTotal", Vector2( stretchWidth, stretchHeight ) );
     }
+    else
+    {
+      sampler.RegisterProperty( "uNinePatchFactorsX[0]", Vector2::ZERO );
+      sampler.RegisterProperty( "uNinePatchFactorsY[0]", Vector2::ZERO );
+
+      RegisterStretchProperties( sampler, "uNinePatchFactorsX", mStretchPixelsX, mImageSize.GetWidth() );
+      RegisterStretchProperties( sampler, "uNinePatchFactorsY", mStretchPixelsY, mImageSize.GetHeight() );
+    }
   }
 }
 
index 77ba2a4..bbb069c 100644 (file)
@@ -183,8 +183,6 @@ private:
 
   NinePatchImage mImage; ///< The image to render if the renderer was set from an NinePatchImage, empty otherwise
   Image mCroppedImage;
-  Geometry mNinePatchGeometry;
-  Geometry mNinePatchBorderGeometry;
 
   std::string mImageUrl; ///< The url to the image resource to render if the renderer was set from an image resource url, empty otherwise
   NinePatchImage::StretchRanges mStretchPixelsX;