Merge "[4.0] Add Delete Key event in TextController" into tizen_4.0
authorSeoyeon Kim <seoyeon2.kim@samsung.com>
Mon, 27 Nov 2017 02:04:18 +0000 (02:04 +0000)
committerGerrit Code Review <gerrit@review.ap-northeast-2.compute.internal>
Mon, 27 Nov 2017 02:04:19 +0000 (02:04 +0000)
15 files changed:
automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/toolkit-text-utils.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Layout.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-application.cpp
automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp
automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp
dali-toolkit/internal/controls/bloom-view/bloom-view-impl.cpp
dali-toolkit/internal/controls/control/control-data-impl.cpp
dali-toolkit/internal/text/layouts/layout-engine.cpp
dali-toolkit/internal/text/layouts/layout-parameters.h
dali-toolkit/internal/text/text-controller.cpp
dali-toolkit/internal/visuals/image/image-visual.cpp
dali-toolkit/public-api/controls/control.h
dali-toolkit/public-api/controls/image-view/image-view.h
dali-toolkit/public-api/dali-toolkit-version.cpp
packaging/dali-toolkit.spec

index 1c844c5..9248151 100644 (file)
@@ -269,7 +269,7 @@ void CreateTextModel( const std::string& text,
   // Set the layout parameters.
   const Vector<GlyphIndex>& charactersToGlyph = visualModel->mCharactersToGlyph;
   const Vector<Length>& glyphsPerCharacter = visualModel->mGlyphsPerCharacter;
-
+  float outlineWidth = visualModel->GetOutlineWidth();
   Layout::Parameters layoutParameters( textArea,
                                        utf32Characters.Begin(),
                                        lineBreakInfo.Begin(),
@@ -282,7 +282,8 @@ void CreateTextModel( const std::string& text,
                                        glyphsPerCharacter.Begin(),
                                        numberOfGlyphs,
                                        Text::HorizontalAlignment::BEGIN,
-                                       Text::LineWrap::WORD );
+                                       Text::LineWrap::WORD,
+                                       outlineWidth );
 
   Vector<LineRun>& lines = visualModel->mLines;
 
index f6c58db..b521976 100644 (file)
@@ -157,6 +157,7 @@ bool LayoutTextTest( const LayoutTextData& data )
   engine.SetLayout( data.layout );
 
   const Length totalNumberOfGlyphs = visualModel->mGlyphs.Count();
+  float outlineWidth = visualModel->GetOutlineWidth();
 
   Layout::Parameters layoutParameters( data.textArea,
                                        logicalModel->mText.Begin(),
@@ -170,7 +171,8 @@ bool LayoutTextTest( const LayoutTextData& data )
                                        visualModel->mGlyphsPerCharacter.Begin(),
                                        totalNumberOfGlyphs,
                                        Text::HorizontalAlignment::BEGIN,
-                                       Text::LineWrap::WORD );
+                                       Text::LineWrap::WORD,
+                                       outlineWidth );
 
   layoutParameters.isLastNewParagraph = isLastNewParagraph;
 
@@ -374,6 +376,7 @@ bool ReLayoutRightToLeftLinesTest( const ReLayoutRightToLeftLinesData& data )
   Layout::Engine engine;
   engine.SetMetrics( metrics );
 
+  float outlineWidth = visualModel->GetOutlineWidth();
   Layout::Parameters layoutParameters( data.textArea,
                                        logicalModel->mText.Begin(),
                                        logicalModel->mLineBreakInfo.Begin(),
@@ -386,7 +389,8 @@ bool ReLayoutRightToLeftLinesTest( const ReLayoutRightToLeftLinesData& data )
                                        visualModel->mGlyphsPerCharacter.Begin(),
                                        visualModel->mGlyphs.Count(),
                                        Text::HorizontalAlignment::BEGIN,
-                                       Text::LineWrap::WORD );
+                                       Text::LineWrap::WORD,
+                                       outlineWidth );
 
   layoutParameters.numberOfBidirectionalInfoRuns = logicalModel->mBidirectionalLineInfo.Count();
   layoutParameters.lineBidirectionalInfoRunsBuffer = logicalModel->mBidirectionalLineInfo.Begin();
index 6636676..a247f7d 100644 (file)
@@ -62,13 +62,15 @@ void TestApplication::Initialize()
   // We always need the first update!
   mStatus.keepUpdating = Integration::KeepUpdating::STAGE_KEEP_RENDERING;
 
-  mCore = Dali::Integration::Core::New(
-    mRenderController,
-    mPlatformAbstraction,
-    mGlAbstraction,
-    mGlSyncAbstraction,
-    mGestureManager,
-    mDataRetentionPolicy);
+  mCore = Dali::Integration::Core::New( mRenderController,
+                                        mPlatformAbstraction,
+                                        mGlAbstraction,
+                                        mGlSyncAbstraction,
+                                        mGestureManager,
+                                        mDataRetentionPolicy,
+                                        Integration::RenderToFrameBuffer::FALSE,
+                                        Integration::DepthBufferAvailable::TRUE,
+                                        Integration::StencilBufferAvailable::TRUE );
 
   mCore->ContextCreated();
   mCore->SurfaceResized( mSurfaceWidth, mSurfaceHeight );
@@ -171,7 +173,7 @@ void TestApplication::DoUpdate( unsigned int intervalMilliseconds, const char* l
   unsigned int nextVSyncTime = mLastVSyncTime + intervalMilliseconds;
   float elapsedSeconds = intervalMilliseconds / 1e3f;
 
-  mCore->Update( elapsedSeconds, mLastVSyncTime, nextVSyncTime, mStatus );
+  mCore->Update( elapsedSeconds, mLastVSyncTime, nextVSyncTime, mStatus, false, false );
 
   GetRenderController().Initialize();
 
index c8cf88f..a770a77 100644 (file)
@@ -25,6 +25,7 @@
 #include <dali-toolkit/devel-api/controls/control-devel.h>
 #include <dali-toolkit/devel-api/image-loader/texture-manager.h>
 #include <dali-toolkit/devel-api/visual-factory/visual-base.h>
+#include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
 
 #include <test-native-image.h>
 #include <sstream>
@@ -1507,3 +1508,108 @@ int UtcDaliImageViewReplaceImageAndGetNaturalSize(void)
 
   END_TEST;
 }
+
+int UtcDaliImageViewResourceReadySignalWithImmediateLoad(void)
+{
+  tet_infoline("Test Setting Image with IMMEDIATE load and receving ResourceReadySignal before staged.");
+
+  ToolkitTestApplication application;
+
+  gResourceReadySignalFired = false;
+
+  Property::Map imageMap;
+
+  imageMap[ ImageVisual::Property::URL ] = gImage_34_RGBA;
+  imageMap[ DevelImageVisual::Property::LOAD_POLICY ] =  DevelImageVisual::LoadPolicy::IMMEDIATE;
+
+  tet_infoline("Creating ImageView without URL so image does not start loading");
+  ImageView imageView = ImageView::New();
+  tet_infoline("Connect to image loaded signal before setting image");
+  imageView.ResourceReadySignal().Connect( &ResourceReadySignal);
+  tet_infoline("Setting Image with IMMEDIATE load, signal already connected so will be triggered.");
+  imageView.SetProperty( ImageView::Property::IMAGE, imageMap );
+
+  // loading started, this waits for the loader thread
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render(16);
+
+  DALI_TEST_EQUALS( gResourceReadySignalFired, true, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliImageViewResourceReadySignalWithReusedImage(void)
+{
+  tet_infoline("Test Setting Image that was already loaded by another ImageView and still getting ResourceReadySignal.");
+
+  ToolkitTestApplication application;
+
+  gResourceReadySignalFired = false;
+
+  Property::Map imageMap;
+
+  imageMap[ ImageVisual::Property::URL ] = gImage_34_RGBA;
+  imageMap[ DevelImageVisual::Property::LOAD_POLICY ] =  DevelImageVisual::LoadPolicy::IMMEDIATE;
+
+  ImageView imageView = ImageView::New();
+  imageView.ResourceReadySignal().Connect( &ResourceReadySignal);
+  imageView.SetProperty( ImageView::Property::IMAGE, imageMap );
+
+  // loading started, this waits for the loader thread
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render(16);
+
+  DALI_TEST_EQUALS( gResourceReadySignalFired, true, TEST_LOCATION );
+  gResourceReadySignalFired = false;
+
+  ImageView imageViewWithExistingImage = ImageView::New();
+  imageViewWithExistingImage.ResourceReadySignal().Connect( &ResourceReadySignal);
+  imageViewWithExistingImage.SetProperty( ImageView::Property::IMAGE, imageMap );
+
+  DALI_TEST_EQUALS( gResourceReadySignalFired, true, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliImageViewResourceReadySignalWithReusedImage02(void)
+{
+  tet_infoline("Test Setting Image that was already loaded by another ImageView and still getting ResourceReadySignal when staged.");
+
+  ToolkitTestApplication application;
+
+  gResourceReadySignalFired = false;
+
+  Property::Map imageImmediateLoadingMap;
+  imageImmediateLoadingMap[ ImageVisual::Property::URL ] = gImage_34_RGBA;
+  imageImmediateLoadingMap[ DevelImageVisual::Property::LOAD_POLICY ] =  DevelImageVisual::LoadPolicy::IMMEDIATE;
+
+  tet_infoline("Immediate load an image");
+  ImageView imageView = ImageView::New();
+  imageView.ResourceReadySignal().Connect( &ResourceReadySignal);
+  imageView.SetProperty( ImageView::Property::IMAGE, imageImmediateLoadingMap );
+
+  // loading started, this waits for the loader thread
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render(16);
+
+  tet_infoline("Check image loaded");
+  DALI_TEST_EQUALS( gResourceReadySignalFired, true, TEST_LOCATION );
+  gResourceReadySignalFired = false;
+
+  tet_infoline("Create another ImageView with the same URL");
+  ImageView imageViewWithExistingImage = ImageView::New( gImage_34_RGBA );
+  tet_infoline("Connect to ResourceReady signal for second ImageView, it should still fire as resource is ready");
+  imageViewWithExistingImage.ResourceReadySignal().Connect( &ResourceReadySignal);
+
+  Stage::GetCurrent().Add( imageViewWithExistingImage );
+
+  DALI_TEST_EQUALS( gResourceReadySignalFired, true, TEST_LOCATION );
+
+  END_TEST;
+}
index 3de6688..679721c 100644 (file)
@@ -59,7 +59,6 @@ void ResourceReadySignal( Control control )
   gResourceReadySignalFired = true;
 }
 
-
 Actor CreateActorWithImageVisual(const Property::Map& map)
 {
   VisualFactory factory = VisualFactory::Get();
@@ -1684,44 +1683,145 @@ int UtcDaliImageVisualLoadPolicy02(void)
 int UtcDaliImageVisualLoadPolicy03(void)
 {
   ToolkitTestApplication application;
-  tet_infoline( "UtcDaliImageVisualLoadPolicy03 Load a visual image before attaching to stage and receive ResourceReady signal" );
+  tet_infoline( "UtcDaliImageVisualLoadPolicy03 Load a visual image and receive ResourceReady Signal when loaded" );
+
+  const bool VISUAL_NOT_ENABLED( false ); // Instead of just passing 'false' into an API.
 
   // Set up trace debug
   TestGlAbstraction& gl = application.GetGlAbstraction();
   TraceCallStack& textureTrace = gl.GetTextureTrace();
   textureTrace.Enable(true);
 
+  tet_infoline( "Create a control and connect to resource ready signal without adding to stage" );
+  DummyControl actor = DummyControl::New(true);
+  actor.ResourceReadySignal().Connect( &ResourceReadySignal);
+  Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(actor.GetImplementation());
+  actor.SetSize(200.f, 200.f);
+
   tet_infoline( "Create visual with IMMEDIATE load policy" );
   Visual::Base imageVisual = CreateVisualWithPolicy( TEST_IMAGE_FILE_NAME, DevelImageVisual::Property::LOAD_POLICY, DevelImageVisual::LoadPolicy::IMMEDIATE );
 
-  // Wait for image to load, ResourceReady signal will not be emitted until Visual is registered with a control and on stage.
+  tet_infoline( "Registering visual allows control to get a signal once loaded even if visual not enabled( not staged )" );
+  dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, imageVisual, VISUAL_NOT_ENABLED );
+  imageVisual.Reset(); // reduce ref count so only the control keeps the visual alive.
+
+  tet_infoline( "Allow image time to load resource" );
   DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+  application.SendNotification();
+  application.Render();
 
   // Ensure texture has been uploaded
+  DALI_TEST_EQUALS( textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION );
+  DALI_TEST_EQUALS( gResourceReadySignalFired, true, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliImageVisualLoadPolicy04(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliImageVisualLoadPolicy04 First part  Load a visual image before attaching to stage");
+  tet_infoline( "Second part, Reuse the same image in aonther control and check resource ready signal fired" );
+
+  const bool VISUAL_NOT_ENABLED( false ); // Instead of just passing false into an API.
+
+  // Set up trace debug
+  TestGlAbstraction& gl = application.GetGlAbstraction();
+  TraceCallStack& textureTrace = gl.GetTextureTrace();
+  textureTrace.Enable(true);
+
+  tet_infoline( "Create a control and connect to resource ready signal" );
+  DummyControl actor = DummyControl::New(true);
+  actor.ResourceReadySignal().Connect( &ResourceReadySignal);
+  Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(actor.GetImplementation());
+  actor.SetSize(200.f, 200.f);
+
+  tet_infoline( "Create visual with IMMEDIATE load policy" );
+  Visual::Base imageVisual = CreateVisualWithPolicy( TEST_IMAGE_FILE_NAME, DevelImageVisual::Property::LOAD_POLICY, DevelImageVisual::LoadPolicy::IMMEDIATE );
+
+  tet_infoline( "Registering visual allows control to get a signal once loaded even if visual not enabled( staged )" );
+  dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, imageVisual, VISUAL_NOT_ENABLED );
+  imageVisual.Reset(); // reduce ref count so only the control keeps the visual alive.
+
+  tet_infoline( "Allow image time to load" );
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
   application.SendNotification();
   application.Render();
 
-  tet_infoline( "Ensure texture loading starts after visual created" );
+  tet_infoline( "Testing texture is loaded and resource ready signal fired" );
   DALI_TEST_EQUALS( textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION );
-  textureTrace.Reset();
+  DALI_TEST_EQUALS( gResourceReadySignalFired, true, TEST_LOCATION );
 
-  tet_infoline( "Register visuals with control and ensure it has the only handles" );
+  tet_infoline( "Original control correctly signalled, now testing for signal with new Control reusing the image" );
+
+  gResourceReadySignalFired = false; // Reset signal check ready for testing next Control
+  Visual::Base imageVisual2 = CreateVisualWithPolicy( TEST_IMAGE_FILE_NAME, DevelImageVisual::Property::LOAD_POLICY, DevelImageVisual::LoadPolicy::IMMEDIATE );
+  DummyControl actor2 = DummyControl::New(true);
+  Impl::DummyControl& dummyImpl2 = static_cast<Impl::DummyControl&>(actor.GetImplementation());
+  actor2.ResourceReadySignal().Connect( &ResourceReadySignal);
+
+  tet_infoline( "Registering visual this should trigger the loading signal as is already image loaded for previous control" );
+  dummyImpl2.RegisterVisual( DummyControl::Property::TEST_VISUAL, imageVisual2 );
+  imageVisual2.Reset(); // reduce ref count so only the control keeps the visual alive.
+  actor2.SetSize(200.f, 200.f);
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 0 ), true, TEST_LOCATION ); // Not expecting any further loading as texture is being reused.
+  DALI_TEST_EQUALS( gResourceReadySignalFired, true, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliImageVisualLoadPolicy05(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliImageVisualLoadPolicy05 LoadPolicy::ATTACHED (default) First part  Load a visual image before attaching to stage");
+  tet_infoline( "Second part, Reuse the same image in aonther control and check resource ready signal fired" );
+  // Set up trace debug
+  TestGlAbstraction& gl = application.GetGlAbstraction();
+  TraceCallStack& textureTrace = gl.GetTextureTrace();
+  textureTrace.Enable(true);
+
+  tet_infoline( "Create a control and connect to resource ready signal" );
   DummyControl actor = DummyControl::New(true);
   actor.ResourceReadySignal().Connect( &ResourceReadySignal);
   Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(actor.GetImplementation());
+  actor.SetSize(200.f, 200.f);
+  Stage::GetCurrent().Add( actor );
 
-  tet_infoline( "Registering visual attaches it to stage and trigger the loading signal if Image loaded" );
+  tet_infoline( "Create visual with ATTACHED load policy" );
+  Visual::Base imageVisual = CreateVisualWithPolicy( TEST_IMAGE_FILE_NAME, DevelImageVisual::Property::LOAD_POLICY, DevelImageVisual::LoadPolicy::ATTACHED );
+
+  tet_infoline( "Registering visual allows control to get a signal once loaded" );
   dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, imageVisual );
   imageVisual.Reset(); // reduce ref count so only the control keeps the visual alive.
-  actor.SetSize(200.f, 200.f);
-  // Adding the Control hence Visual to stage will cause the Visual to trigger ResourceReadySignal if the image is already loaded.
-  Stage::GetCurrent().Add( actor ); // If LoadPolicy was not IMMEDIATE then as this point (after attached to stage) the test would need to wait for Loading
 
+  tet_infoline( "Allow image time to load" );
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+  application.SendNotification();
+  application.Render();
+
+  tet_infoline( "Testing texture is loaded and resource ready signal fired" );
+  DALI_TEST_EQUALS( textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION );
+  DALI_TEST_EQUALS( gResourceReadySignalFired, true, TEST_LOCATION );
+
+  tet_infoline( "Original control correctly signalled, now testing for signal with new Control reusing the image" );
+
+  gResourceReadySignalFired = false; // Reset signal check ready for testing next Control
+  Visual::Base imageVisual2 = CreateVisualWithPolicy( TEST_IMAGE_FILE_NAME, DevelImageVisual::Property::LOAD_POLICY, DevelImageVisual::LoadPolicy::ATTACHED );
+  DummyControl actor2 = DummyControl::New(true);
+  Impl::DummyControl& dummyImpl2 = static_cast<Impl::DummyControl&>(actor.GetImplementation());
+  actor2.ResourceReadySignal().Connect( &ResourceReadySignal);
+
+  tet_infoline( "Registering visual this should trigger the loading signal as is already image loaded for previous control" );
+  dummyImpl2.RegisterVisual( DummyControl::Property::TEST_VISUAL, imageVisual2 );
+  imageVisual2.Reset(); // reduce ref count so only the control keeps the visual alive.
+  actor2.SetSize(200.f, 200.f);
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 0 ), true, TEST_LOCATION ); // Not expecting any further loading as texture is being reused.
   DALI_TEST_EQUALS( gResourceReadySignalFired, true, TEST_LOCATION );
 
   END_TEST;
 }
 
+
 int UtcDaliImageVisualOrientationCorrection(void)
 {
   ToolkitTestApplication application;
index 1a1f9f0..c05e954 100644 (file)
@@ -358,6 +358,7 @@ void BloomView::AllocateResources()
     mGaussianBlurView.SetSize(mTargetSize);
     GetImpl(mGaussianBlurView).AllocateResources();
 
+    mGaussianBlurView.SetVisible( true );
 
     //////////////////////////////////////////////////////
     // Create render targets
@@ -458,9 +459,18 @@ void BloomView::Deactivate()
   // stop render tasks processing
   // Note: render target resources are automatically freed since we set the Image::Unused flag
   RemoveRenderTasks();
+
   mRenderTargetForRenderingChildren.Reset();
   mBloomExtractTarget.Reset();
   mOutputRenderTarget.Reset();
+
+  // Reset children
+  mBloomExtractImageView.SetImage( "" );
+  mTargetImageView.SetImage( "" );
+  mCompositeImageView.SetImage( "" );
+
+  mGaussianBlurView.SetVisible( false );
+
   mActivated = false;
 }
 
index 6ff1efb..1630b92 100644 (file)
@@ -525,12 +525,17 @@ void Control::Impl::RegisterVisual( Property::Index index, Toolkit::Visual::Base
                                              ( visualReplaced && enabled ) ) ;
     mVisuals.PushBack( newRegisteredVisual );
 
+    Internal::Visual::Base& visualImpl = Toolkit::GetImplementation( visual );
     // Put on stage if enabled and the control is already on the stage
-    // Visual must be set on stage for the renderer to be created and the ResourceReady triggered.
     if( ( enabled == VisualState::ENABLED ) && self.OnStage() )
     {
-      Toolkit::GetImplementation(visual).SetOnStage( self );
+      visualImpl.SetOnStage( self );
     }
+    else if( visualImpl.IsResourceReady() ) // When not being staged, check if visual already 'ResourceReady' before it was Registered. ( Resource may have been loaded already )
+    {
+      ResourceReady( visualImpl );
+    }
+
   }
 
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::RegisterVisual() Registered %s(%d), enabled:%s\n",  visual.GetName().c_str(), index, enabled?"true":"false" );
@@ -657,8 +662,11 @@ void Control::Impl::ResourceReady( Visual::Base& object)
     }
   }
 
-  // A visual is ready so control may need relayouting
-  mControlImpl.RelayoutRequest();
+  // A visual is ready so control may need relayouting if staged
+  if ( self.OnStage() )
+  {
+    mControlImpl.RelayoutRequest();
+  }
 
   // Emit signal if all enabled visuals registered by the control are ready.
   if( IsResourceReady() )
index 3e633ba..ccd42ae 100644 (file)
@@ -470,6 +470,7 @@ struct Engine::Impl
 
   void SetGlyphPositions( const GlyphInfo* const glyphsBuffer,
                           Length numberOfGlyphs,
+                          float outlineWidth,
                           Vector2* glyphPositionsBuffer )
   {
     // Traverse the glyphs and set the positions.
@@ -479,7 +480,8 @@ struct Engine::Impl
     // so the penX position needs to be moved to the right.
 
     const GlyphInfo& glyph = *glyphsBuffer;
-    float penX = ( 0.f > glyph.xBearing ) ? -glyph.xBearing : 0.f;
+    float penX = ( 0.f > glyph.xBearing ) ? -glyph.xBearing + outlineWidth : outlineWidth;
+
 
     for( GlyphIndex i = 0u; i < numberOfGlyphs; ++i )
     {
@@ -604,6 +606,7 @@ struct Engine::Impl
 
       SetGlyphPositions( layoutParameters.glyphsBuffer + lineRun->glyphRun.glyphIndex,
                          ellipsisLayout.numberOfGlyphs,
+                         layoutParameters.outlineWidth,
                          glyphPositionsBuffer + lineRun->glyphRun.glyphIndex - layoutParameters.startGlyphIndex );
     }
 
@@ -963,6 +966,7 @@ struct Engine::Impl
         // Sets the positions of the glyphs.
         SetGlyphPositions( layoutParameters.glyphsBuffer + index,
                            layout.numberOfGlyphs,
+                           layoutParameters.outlineWidth,
                            glyphPositionsBuffer + index - layoutParameters.startGlyphIndex );
 
         // Updates the vertical pen's position.
@@ -1043,7 +1047,7 @@ struct Engine::Impl
       const CharacterIndex characterVisualIndex = bidiLine.characterRun.characterIndex + *bidiLine.visualToLogicalMap;
       const GlyphInfo& glyph = *( layoutParameters.glyphsBuffer + *( layoutParameters.charactersToGlyphsBuffer + characterVisualIndex ) );
 
-      float penX = ( 0.f > glyph.xBearing ) ? -glyph.xBearing : 0.f;
+      float penX = ( 0.f > glyph.xBearing ) ? -glyph.xBearing - layoutParameters.outlineWidth : -layoutParameters.outlineWidth;
 
       Vector2* glyphPositionsBuffer = glyphPositions.Begin();
 
index 47aed0e..7f3e169 100644 (file)
@@ -73,7 +73,8 @@ struct Parameters
               const Length* const glyphsPerCharacterBuffer,
               Length totalNumberOfGlyphs,
               Text::HorizontalAlignment::Type horizontalAlignment,
-              Text::LineWrap::Mode lineWrapMode )
+              Text::LineWrap::Mode lineWrapMode,
+              float outlineWidth )
   : boundingBox( boundingBox ),
     textBuffer( textBuffer ),
     lineBreakInfoBuffer( lineBreakInfoBuffer ),
@@ -93,7 +94,8 @@ struct Parameters
     startLineIndex( 0u ),
     estimatedNumberOfLines( 0u ),
     lineWrapMode( lineWrapMode ),
-    isLastNewParagraph( false )
+    isLastNewParagraph( false ),
+    outlineWidth( outlineWidth )
   {}
 
   Vector2                         boundingBox;                     ///< The size of the box containing the text.
@@ -116,6 +118,7 @@ struct Parameters
   Length                          estimatedNumberOfLines;          ///< The estimated number of lines.
   Text::LineWrap::Mode            lineWrapMode;                    ///< The line wrap mode for moving to next line.
   bool                            isLastNewParagraph;              ///< Whether the last character is a new paragraph character.
+  float                           outlineWidth;                    ///< The outline width.
 };
 
 } // namespace Layout
index 6f73d66..fe6f520 100755 (executable)
@@ -3328,6 +3328,7 @@ bool Controller::DoRelayout( const Size& size,
     const Vector<CharacterIndex>& glyphsToCharactersMap = mImpl->mModel->mVisualModel->mGlyphsToCharacters;
     const Vector<Length>& charactersPerGlyph = mImpl->mModel->mVisualModel->mCharactersPerGlyph;
     const Character* const textBuffer = mImpl->mModel->mLogicalModel->mText.Begin();
+    float outlineWidth = mImpl->mModel->GetOutlineWidth();
 
     // Set the layout parameters.
     Layout::Parameters layoutParameters( size,
@@ -3342,7 +3343,8 @@ bool Controller::DoRelayout( const Size& size,
                                          glyphsPerCharacterBuffer,
                                          totalNumberOfGlyphs,
                                          mImpl->mModel->mHorizontalAlignment,
-                                         mImpl->mModel->mLineWrapMode );
+                                         mImpl->mModel->mLineWrapMode,
+                                         outlineWidth );
 
     // Resize the vector of positions to have the same size than the vector of glyphs.
     Vector<Vector2>& glyphPositions = mImpl->mModel->mVisualModel->mGlyphPositions;
index 7ef4669..9afcb29 100644 (file)
@@ -276,14 +276,17 @@ ImageVisual::ImageVisual( VisualFactoryCache& factoryCache,
   mMaskingData( ),
   mDesiredSize( size ),
   mTextureId( TextureManager::INVALID_TEXTURE_ID ),
+  mTextures(),
   mFittingMode( fittingMode ),
   mSamplingMode( samplingMode ),
   mWrapModeU( WrapMode::DEFAULT ),
   mWrapModeV( WrapMode::DEFAULT ),
   mLoadPolicy( DevelImageVisual::LoadPolicy::ATTACHED ),
   mReleasePolicy( DevelImageVisual::ReleasePolicy::DETACHED ),
+  mAtlasRect( 0.0f, 0.0f, 0.0f, 0.0f ),
   mAttemptAtlasing( false ),
-  mLoading( false )
+  mLoading( false ),
+  mOrientationCorrection( true )
 {
 }
 
@@ -296,12 +299,14 @@ ImageVisual::ImageVisual( VisualFactoryCache& factoryCache, const Image& image )
   mMaskingData( ),
   mDesiredSize(),
   mTextureId( TextureManager::INVALID_TEXTURE_ID ),
+  mTextures(),
   mFittingMode( FittingMode::DEFAULT ),
   mSamplingMode( SamplingMode::DEFAULT ),
   mWrapModeU( WrapMode::DEFAULT ),
   mWrapModeV( WrapMode::DEFAULT ),
   mLoadPolicy( DevelImageVisual::LoadPolicy::ATTACHED ),
   mReleasePolicy( DevelImageVisual::ReleasePolicy::DESTROYED ),
+  mAtlasRect( 0.0f, 0.0f, 0.0f, 0.0f ),
   mAttemptAtlasing( false ),
   mLoading( false ),
   mOrientationCorrection( true )
@@ -1035,6 +1040,8 @@ void ImageVisual::UploadCompleted()
     // reset the weak handle so that the renderer only get added to actor once
     mPlacementActor.Reset();
   }
+  // Image loaded
+  ResourceReady( Toolkit::Visual::ResourceStatus::READY );
   mLoading = false;
 }
 
@@ -1061,8 +1068,6 @@ void ImageVisual::UploadComplete( bool loadingSuccess, int32_t textureId, Textur
         sampler.SetWrapMode(  mWrapModeU, mWrapModeV  );
         textureSet.SetSampler( 0u, sampler );
         mImpl->mRenderer.SetTextures(textureSet);
-
-        resourceStatus = Toolkit::Visual::ResourceStatus::READY;
       }
       else
       {
@@ -1072,20 +1077,26 @@ void ImageVisual::UploadComplete( bool loadingSuccess, int32_t textureId, Textur
         mImpl->mRenderer.SetTextures( textureSet );
 
         ApplyImageToSampler( brokenImage );
-
-        resourceStatus = Toolkit::Visual::ResourceStatus::FAILED;
       }
-      // Image loaded and ready to display
-      ResourceReady( resourceStatus );
     }
   }
-
   // Storing TextureSet needed when renderer staged.
   if( ! mImpl->mRenderer )
   {
     mTextures = textureSet;
   }
 
+  // Image loaded, set status regardless of staged status.
+  if( loadingSuccess )
+  {
+    resourceStatus = Toolkit::Visual::ResourceStatus::READY;
+  }
+  else
+  {
+    resourceStatus = Toolkit::Visual::ResourceStatus::FAILED;
+  }
+  // Signal to observers ( control ) that resources are ready. Must be all resources.
+  ResourceReady( resourceStatus );
   mLoading = false;
 }
 
index 6d2f7e7..eee3b91 100644 (file)
@@ -450,6 +450,23 @@ public:
    *
    * Most resources are only loaded when the control is placed on stage.
    *
+   * If resources are shared between ImageViews, they are cached.
+   * In this case, the ResourceReady signal may be sent before there is an object to connect to.
+   * To protect against this, IsResourceReady() can be checked first.
+   *
+   * @code
+   *    auto newControl = Control::New();
+   *    newControl.SetResource( resourceUrl );
+   *    if ( newControl.IsResourceReady() )
+   *    {
+   *       // do something
+   *    }
+   *    else
+   *    {
+   *      newControl.ResourceReadySignal.Connect( .... )
+   *    }
+   * @endcode
+   *
    * A callback of the following type may be connected:
    * @code
    *   void YourCallbackName( Control control );
index 69bcbc3..b6f786b 100644 (file)
@@ -44,6 +44,32 @@ class ImageView;
  *
  * An instance of ImageView can be created using a URL or an Image instance.
  *
+ * Some resources can be loaded before the ImageView is staged ( already cached ), in these cases if the connection to
+ * ResouceReadySignal is done after the resource is set then signal will be missed.
+ *
+ * To protect against this, IsResourceReady() can be checked before connecting to ResourceReadySignal,
+ * or the signal connection can be done before setting the resource"
+ *
+ * @code
+ *    auto myImageView = ImageView::New( resourceUrl );
+ *    if ( myImageView.IsResourceReady() )
+ *    {
+ *       // do something
+ *    }
+ *    else
+ *    {
+ *      myImageView.ResourceReadySignal.Connect( .... )
+ *    }
+ * @endcode
+ *
+ * OR Connect to signal before setting resource
+ *
+ * @code
+ *    auto myImageView = ImageView::New( resourceUrl );
+ *    myImageView.ResourceReadySignal.Connect( .... )
+ *    myImageView.SetProperty( ImageView::Property::IMAGE, resourceUrl );
+ * @endcode
+ *
  * @SINCE_1_0.0
  *
  */
index 7b792e9..ae2ff07 100644 (file)
@@ -31,7 +31,7 @@ namespace Toolkit
 
 const unsigned int TOOLKIT_MAJOR_VERSION = 1;
 const unsigned int TOOLKIT_MINOR_VERSION = 2;
-const unsigned int TOOLKIT_MICRO_VERSION = 61003;
+const unsigned int TOOLKIT_MICRO_VERSION = 66;
 const char * const TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index 5ed22a6..799960c 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali-toolkit
 Summary:    Dali 3D engine Toolkit
-Version:    1.2.61.3
+Version:    1.2.66
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT