Merge "TextField is re-laied out after its properties are changed." into devel/master
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Mon, 11 Mar 2019 10:35:32 +0000 (10:35 +0000)
committerGerrit Code Review <gerrit@review.ap-northeast-2.compute.internal>
Mon, 11 Mar 2019 10:35:32 +0000 (10:35 +0000)
111 files changed:
automated-tests/src/dali-toolkit-internal/CMakeLists.txt
automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/toolkit-text-utils.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-DebugRendering.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Circular.cpp [new file with mode: 0755]
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Controller.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Layout.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Markup.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Shaping.cpp [changed mode: 0644->0755]
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-ViewModel.cpp [changed mode: 0644->0755]
automated-tests/src/dali-toolkit-internal/utc-Dali-TextureManager.cpp
automated-tests/src/dali-toolkit-styling/CMakeLists.txt
automated-tests/src/dali-toolkit-third-party/CMakeLists.txt
automated-tests/src/dali-toolkit/CMakeLists.txt
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dali-toolkit-test-suite-utils.cpp [new file with mode: 0644]
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dali-toolkit-test-suite-utils.h
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-application.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-application.h
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-render-surface.cpp [new file with mode: 0644]
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-render-surface.h [new file with mode: 0644]
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-accessibility-adaptor.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor-impl.h
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-event-thread-callback.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-singleton-service.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-animation-renderer.cpp
automated-tests/src/dali-toolkit/utc-Dali-AbsoluteLayout.cpp
automated-tests/src/dali-toolkit/utc-Dali-AccessibilityManager.cpp
automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp
automated-tests/src/dali-toolkit/utc-Dali-Builder.cpp
automated-tests/src/dali-toolkit/utc-Dali-ControlWrapper.cpp
automated-tests/src/dali-toolkit/utc-Dali-GridLayout.cpp
automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp
automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp
automated-tests/src/dali-toolkit/utc-Dali-ScrollViewEffect.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextureManager.cpp
automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp
build/tizen/docs/dali.doxy.in
dali-toolkit/devel-api/controls/control-wrapper-impl.cpp
dali-toolkit/devel-api/file.list
dali-toolkit/devel-api/text/bitmap-font.cpp [new file with mode: 0755]
dali-toolkit/devel-api/text/bitmap-font.h [new file with mode: 0755]
dali-toolkit/devel-api/text/text-utils-devel.cpp [new file with mode: 0755]
dali-toolkit/devel-api/text/text-utils-devel.h [new file with mode: 0755]
dali-toolkit/devel-api/visuals/animated-vector-image-visual-actions-devel.h
dali-toolkit/devel-api/visuals/image-visual-properties-devel.h
dali-toolkit/internal/accessibility-manager/accessibility-manager-impl.cpp
dali-toolkit/internal/accessibility-manager/accessibility-manager-impl.h
dali-toolkit/internal/feedback/feedback-style.cpp
dali-toolkit/internal/feedback/feedback-style.h
dali-toolkit/internal/file.list
dali-toolkit/internal/layouting/grid-impl.cpp
dali-toolkit/internal/layouting/grid-locations.cpp
dali-toolkit/internal/layouting/grid-locations.h
dali-toolkit/internal/layouting/layout-controller-impl.cpp
dali-toolkit/internal/layouting/layout-controller-impl.h
dali-toolkit/internal/text/character-run.h
dali-toolkit/internal/text/embedded-item.h [new file with mode: 0755]
dali-toolkit/internal/text/font-description-run.h
dali-toolkit/internal/text/font-run.h
dali-toolkit/internal/text/glyph-metrics-helper.cpp [changed mode: 0644->0755]
dali-toolkit/internal/text/layouts/layout-engine.cpp
dali-toolkit/internal/text/logical-model-impl.cpp [changed mode: 0644->0755]
dali-toolkit/internal/text/logical-model-impl.h [changed mode: 0644->0755]
dali-toolkit/internal/text/markup-processor-embedded-item.cpp [new file with mode: 0755]
dali-toolkit/internal/text/markup-processor-embedded-item.h [new file with mode: 0755]
dali-toolkit/internal/text/markup-processor-helper-functions.cpp [changed mode: 0644->0755]
dali-toolkit/internal/text/markup-processor-helper-functions.h [changed mode: 0644->0755]
dali-toolkit/internal/text/markup-processor.cpp
dali-toolkit/internal/text/markup-processor.h [changed mode: 0644->0755]
dali-toolkit/internal/text/metrics.h [changed mode: 0644->0755]
dali-toolkit/internal/text/multi-language-support-impl.cpp
dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.cpp
dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.h
dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.cpp
dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager.h
dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp
dali-toolkit/internal/text/rendering/text-typesetter.cpp
dali-toolkit/internal/text/rendering/view-model.cpp
dali-toolkit/internal/text/rendering/view-model.h
dali-toolkit/internal/text/shaper.cpp
dali-toolkit/internal/text/text-controller.cpp
dali-toolkit/internal/text/text-controller.h
dali-toolkit/internal/text/text-definitions.h [changed mode: 0644->0755]
dali-toolkit/internal/text/text-effects-style.cpp
dali-toolkit/internal/text/text-model-interface.h
dali-toolkit/internal/text/text-model.cpp
dali-toolkit/internal/text/text-model.h
dali-toolkit/internal/text/text-view-interface.h [changed mode: 0644->0755]
dali-toolkit/internal/text/text-view.cpp [changed mode: 0644->0755]
dali-toolkit/internal/text/text-view.h [changed mode: 0644->0755]
dali-toolkit/internal/text/visual-model-impl.cpp
dali-toolkit/internal/text/visual-model-impl.h
dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp
dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h
dali-toolkit/internal/visuals/animated-vector-image/vector-rasterize-thread.cpp
dali-toolkit/internal/visuals/animated-vector-image/vector-rasterize-thread.h
dali-toolkit/internal/visuals/image/image-visual.cpp
dali-toolkit/internal/visuals/npatch/npatch-visual.cpp
dali-toolkit/internal/visuals/texture-manager-impl.cpp
dali-toolkit/internal/visuals/texture-manager-impl.h
dali-toolkit/internal/visuals/visual-factory-impl.cpp
dali-toolkit/internal/visuals/visual-string-constants.cpp
dali-toolkit/internal/visuals/visual-string-constants.h
dali-toolkit/public-api/accessibility-manager/accessibility-manager.cpp
dali-toolkit/public-api/accessibility-manager/accessibility-manager.h
dali-toolkit/public-api/dali-toolkit-version.cpp
dali-toolkit/third-party/base-n/basen.hpp
packaging/dali-toolkit.spec

index 7a71661..5e2e9ed 100755 (executable)
@@ -16,6 +16,7 @@ SET(TC_SOURCES
  utc-Dali-PropertyHelper.cpp
  utc-Dali-SizeNegotiationMapper.cpp
  utc-Dali-Text-CharacterSetConversion.cpp
+ utc-Dali-Text-Circular.cpp
  utc-Dali-Text-Controller.cpp
  utc-Dali-Text-Cursor.cpp
  utc-Dali-Text-Layout.cpp
@@ -49,6 +50,7 @@ LIST(APPEND TC_SOURCES
    ../dali-toolkit/dali-toolkit-test-utils/toolkit-tts-player.cpp
    ../dali-toolkit/dali-toolkit-test-utils/toolkit-vector-animation-renderer.cpp
    ../dali-toolkit/dali-toolkit-test-utils/dali-test-suite-utils.cpp
+   ../dali-toolkit/dali-toolkit-test-utils/dali-toolkit-test-suite-utils.cpp
    ../dali-toolkit/dali-toolkit-test-utils/dummy-control.cpp
    ../dali-toolkit/dali-toolkit-test-utils/mesh-builder.cpp
    ../dali-toolkit/dali-toolkit-test-utils/test-actor-utils.cpp
@@ -61,6 +63,7 @@ LIST(APPEND TC_SOURCES
    ../dali-toolkit/dali-toolkit-test-utils/test-gl-sync-abstraction.cpp
    ../dali-toolkit/dali-toolkit-test-utils/test-platform-abstraction.cpp
    ../dali-toolkit/dali-toolkit-test-utils/test-render-controller.cpp
+   ../dali-toolkit/dali-toolkit-test-utils/test-render-surface.cpp
    ../dali-toolkit/dali-toolkit-test-utils/test-trace-call-stack.cpp
    ../dali-toolkit/dali-toolkit-test-utils/test-native-image.cpp
    dali-toolkit-test-utils/toolkit-text-utils.cpp
index 84df087..e3ccad8 100755 (executable)
@@ -108,7 +108,8 @@ void CreateTextModel( const std::string& text,
   visualModel = VisualModel::New();
 
   MarkupProcessData markupProcessData( logicalModel->mColorRuns,
-                                       logicalModel->mFontDescriptionRuns );
+                                       logicalModel->mFontDescriptionRuns,
+                                       logicalModel->mEmbeddedItems );
 
   Length textSize = 0u;
   const uint8_t* utf8 = NULL;
index 71641fb..80f2113 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -190,7 +190,7 @@ int UtcDaliDebugRenderingGetVisual1(void)
   DALI_TEST_EQUALS( naturalSize, Vector2( 80.f, 20.f ), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
 
   const float height = textVisual.GetHeightForWidth( 40.f );
-  DALI_TEST_EQUALS( height, 40.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+  DALI_TEST_EQUALS( height, 38.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
 
   // Test that NPatchVisual is replaced with debug visual
   // TEST_NPATCH_FILE_NAME: image_01.9.jpg
diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Circular.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Circular.cpp
new file mode 100755 (executable)
index 0000000..4c94126
--- /dev/null
@@ -0,0 +1,893 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <iostream>
+#include <fstream>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <toolkit-text-utils.h>
+
+// EXTERNAL INCLUDES
+#include <dali-toolkit/devel-api/text/bitmap-font.h>
+#include <dali/devel-api/text-abstraction/bitmap-font.h>
+#include <dali-toolkit/devel-api/text/text-utils-devel.h>
+#include <devel-api/adaptor-framework/image-loading.h>
+
+
+
+using namespace std;
+using namespace Dali;
+using namespace Toolkit;
+using namespace Text;
+
+namespace
+{
+const std::string TEST_IMAGE_FILE_NAME1 =  TEST_RESOURCE_DIR  "/application-icon-20.png";
+const std::string TEST_IMAGE_FILE_NAME2 =  TEST_RESOURCE_DIR  "/application-icon-26.png";
+
+const std::vector<std::string> embeddedItems = { TEST_IMAGE_FILE_NAME2, TEST_IMAGE_FILE_NAME2, TEST_IMAGE_FILE_NAME2, TEST_IMAGE_FILE_NAME2, TEST_IMAGE_FILE_NAME2 };
+
+struct CircularTextData
+{
+  std::string                      description;
+  std::string                      text;
+  DevelText::RendererParameters&   textParameters;
+  const std::vector<std::string>&  embeddedItems;
+  bool                             blend:1;
+};
+
+
+bool CircularRenderTest( const CircularTextData& data )
+{
+  bool ret = true;
+
+  Dali::Vector<Dali::Toolkit::DevelText::EmbeddedItemInfo> embeddedItemLayout;
+
+  Devel::PixelBuffer pixelBuffer = Toolkit::DevelText::Render( data.textParameters, embeddedItemLayout );
+
+   const int dstWidth = static_cast<int>( pixelBuffer.GetWidth() );
+   const int dstHeight = static_cast<int>( pixelBuffer.GetHeight() );
+
+   unsigned int index = 0u;
+   for( const auto& itemLayout : embeddedItemLayout )
+   {
+     int width = static_cast<int>( itemLayout.size.width );
+     int height = static_cast<int>( itemLayout.size.height );
+     int x = static_cast<int>( itemLayout.position.x );
+     int y = static_cast<int>( itemLayout.position.y );
+
+     Dali::Devel::PixelBuffer itemPixelBuffer = Dali::LoadImageFromFile( data.embeddedItems[index++] );
+     itemPixelBuffer.Resize( width, height );
+     itemPixelBuffer.Rotate( itemLayout.angle );
+
+     width = static_cast<int>( itemPixelBuffer.GetWidth() );
+     height = static_cast<int>( itemPixelBuffer.GetHeight() );
+
+     Dali::Pixel::Format itemPixelFormat = itemPixelBuffer.GetPixelFormat();
+
+     // Check if the item is out of the buffer.
+     if( ( x + width < 0 ) ||
+         ( x > dstWidth ) ||
+         ( y < 0 ) ||
+         ( y - height > dstHeight ) )
+     {
+       // The embedded item is completely out of the buffer.
+       continue;
+     }
+
+     // Crop if it exceeds the boundaries of the destination buffer.
+     int layoutX = 0;
+     int layoutY = 0;
+     int cropX = 0;
+     int cropY = 0;
+     int newWidth = width;
+     int newHeight = height;
+
+     bool crop = false;
+
+     if( 0 > x )
+     {
+       newWidth += x;
+       cropX = std::abs( x );
+       crop = true;
+     }
+     else
+     {
+       layoutX = x;
+     }
+
+     if( cropX + newWidth > dstWidth )
+     {
+       crop = true;
+       newWidth -= ( ( cropX + newWidth ) - dstWidth );
+     }
+
+     layoutY = y;
+     if( 0.f > layoutY )
+     {
+       newHeight += layoutY;
+       cropY = std::abs(layoutY);
+       crop = true;
+     }
+
+     if( cropY + newHeight > dstHeight )
+     {
+       crop = true;
+       newHeight -= ( ( cropY + newHeight ) - dstHeight );
+     }
+
+     uint16_t uiCropX = static_cast<uint16_t>(cropX);
+     uint16_t uiCropY = static_cast<uint16_t>(cropY);
+     uint16_t uiNewWidth = static_cast<uint16_t>(newWidth);
+     uint16_t uiNewHeight = static_cast<uint16_t>(newHeight);
+
+     if( crop )
+     {
+       itemPixelBuffer.Crop( uiCropX, uiCropY, uiNewWidth, uiNewHeight );
+     }
+
+     // Blend the item pixel buffer with the text's color according its blending mode.
+     if( Dali::TextAbstraction::ColorBlendingMode::MULTIPLY == itemLayout.colorBlendingMode )
+     {
+       Dali::Devel::PixelBuffer buffer = Dali::Devel::PixelBuffer::New( uiNewWidth,
+                                                                        uiNewHeight,
+                                                                        itemPixelFormat );
+
+       unsigned char* bufferPtr = buffer.GetBuffer();
+       const unsigned char* itemBufferPtr = itemPixelBuffer.GetBuffer();
+       const unsigned int bytesPerPixel = Dali::Pixel::GetBytesPerPixel(itemPixelFormat);
+       const unsigned int size = uiNewWidth * uiNewHeight * bytesPerPixel;
+
+       for (unsigned int i = 0u; i < size; i += bytesPerPixel)
+       {
+         *(bufferPtr + 0u) = static_cast<unsigned char>( static_cast<float>( *(itemBufferPtr + 0u) ) * data.textParameters.textColor.r );
+         *(bufferPtr + 1u) = static_cast<unsigned char>( static_cast<float>( *(itemBufferPtr + 1u) ) * data.textParameters.textColor.g );
+         *(bufferPtr + 2u) = static_cast<unsigned char>( static_cast<float>( *(itemBufferPtr + 2u) ) * data.textParameters.textColor.b );
+         *(bufferPtr + 3u) = static_cast<unsigned char>( static_cast<float>( *(itemBufferPtr + 3u) ) * data.textParameters.textColor.a );
+
+         itemBufferPtr += bytesPerPixel;
+         bufferPtr += bytesPerPixel;
+       }
+
+       itemPixelBuffer = buffer;
+     }
+
+     Dali::Toolkit::DevelText::UpdateBuffer(itemPixelBuffer, pixelBuffer, layoutX, layoutY, data.blend);
+   }
+
+  return  ret;
+}
+
+} // namespace
+
+int UtcDaliTextCircularBitmapFont(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextCircularBitmapFont");
+
+  Dali::Toolkit::DevelText::BitmapFontDescription description;
+  Dali::Toolkit::DevelText::Glyph glyph;
+  glyph.url = "BitmapFontUrl";
+  glyph.utf8 = "BitmapFontUrl";
+  glyph.ascender = 1.f;
+  glyph.descender = 1.f;
+  description.glyphs.push_back( glyph );
+
+  TextAbstraction::BitmapFont bitmapFont;
+  Dali::Toolkit::DevelText::CreateBitmapFont( description, bitmapFont );
+
+  for( const auto& bitmapGlyph : bitmapFont.glyphs )
+  {
+    if( glyph.url != bitmapGlyph.url )
+    {
+      std::cout << "  different output string : " << bitmapGlyph.url << ", expected : " << glyph.url << " " << std::endl;
+      tet_result(TET_FAIL);
+    }
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextCircularShadowText(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextCircularShadowText");
+
+  Dali::Toolkit::DevelText::ShadowParameters shadowParameters;
+  Devel::PixelBuffer outPixelBuffer;
+  shadowParameters.input = Devel::PixelBuffer::New( 100, 100, Pixel::RGBA8888 );
+  shadowParameters.textColor = Color::BLACK;
+  shadowParameters.color =  Color::BLACK;
+  shadowParameters.offset.x = 10u;
+  shadowParameters.offset.y = 10u;
+  shadowParameters.blendShadow = true;
+  outPixelBuffer = Dali::Toolkit::DevelText::CreateShadow( shadowParameters );
+  DALI_TEST_CHECK( outPixelBuffer );
+  DALI_TEST_EQUALS( outPixelBuffer.GetPixelFormat(), Pixel::RGBA8888, TEST_LOCATION  );
+
+  shadowParameters.blendShadow = false;
+  outPixelBuffer = Dali::Toolkit::DevelText::CreateShadow( shadowParameters );
+  DALI_TEST_CHECK( outPixelBuffer );
+  DALI_TEST_EQUALS( outPixelBuffer.GetPixelFormat(), Pixel::RGBA8888, TEST_LOCATION  );
+
+  shadowParameters.input = Devel::PixelBuffer::New( 100, 100, Pixel::A8 );
+  outPixelBuffer = Dali::Toolkit::DevelText::CreateShadow( shadowParameters );
+  DALI_TEST_CHECK( outPixelBuffer );
+  DALI_TEST_EQUALS( outPixelBuffer.GetPixelFormat(), Pixel::RGBA8888, TEST_LOCATION  );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextCircularPixelBufferText(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextCircularPixelBufferText");
+
+  Devel::PixelBuffer pixbuf = Devel::PixelBuffer::New( 10, 10, Pixel::A8 );
+  Vector4 color;
+  Devel::PixelBuffer pixelBufferRgba = Dali::Toolkit::DevelText::ConvertToRgba8888( pixbuf, color, true );
+  pixelBufferRgba = Dali::Toolkit::DevelText::ConvertToRgba8888( pixbuf, color, false );
+  DALI_TEST_CHECK( pixelBufferRgba );
+  DALI_TEST_EQUALS( pixelBufferRgba.GetPixelFormat(), Pixel::RGBA8888, TEST_LOCATION  );
+
+  pixbuf = Devel::PixelBuffer::New( 10, 10, Pixel::RGBA8888 );
+  pixelBufferRgba = Dali::Toolkit::DevelText::ConvertToRgba8888( pixbuf, color, false );
+  DALI_TEST_CHECK( pixelBufferRgba );
+  DALI_TEST_EQUALS( pixelBufferRgba.GetPixelFormat(), Pixel::RGBA8888, TEST_LOCATION  );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextCircularNoText(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextCircularNoText");
+
+  Dali::Toolkit::DevelText::RendererParameters textParameters;
+  textParameters.text = "";
+  textParameters.fontSize = 25.f;
+  textParameters.textWidth = 360u;
+  textParameters.textHeight = 360u;
+
+  CircularTextData data =
+  {
+      "No text",
+      "",
+      textParameters,
+      embeddedItems,
+      true
+  };
+
+  if( !CircularRenderTest( data ) )
+  {
+    tet_result(TET_FAIL);
+  }
+
+  textParameters.text = "<item 'width'=26 'height'=26/>";
+  textParameters.markupEnabled = true;
+  if( !CircularRenderTest( data ) )
+  {
+    tet_result(TET_FAIL);
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextCircularIncrementAngle(void)
+{
+
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextCircularIncrementAngle");
+
+  const std::string image1 = "<item 'width'=26 'height'=26 'url'='" + TEST_IMAGE_FILE_NAME1 + "'/>";
+  const std::string image2 = "<item 'width'=26 'height'=26/>";
+
+  Dali::Toolkit::DevelText::RendererParameters textParameters;
+  textParameters.text = "Hello " + image1 + " world " + image2 + " this " + image1 + " is " + image2 + " a " + image1 + " demo " + image2 + " of " + image1 + " circular " + image2 + " text " + image1 + " width " + image2 + " icons.";
+  textParameters.horizontalAlignment = "center";
+  textParameters.verticalAlignment = "center";
+  textParameters.circularAlignment = "center";
+  textParameters.fontFamily = "SamsungUI";
+  textParameters.fontWeight = "";
+  textParameters.fontWidth = "";
+  textParameters.fontSlant = "";
+  textParameters.layout = "circular";
+  textParameters.textColor = Color::BLACK;
+  textParameters.fontSize = 25.f;
+  textParameters.textWidth = 360u;
+  textParameters.textHeight = 360u;
+  textParameters.radius = 180u;
+  textParameters.beginAngle = 15.f;
+  textParameters.incrementAngle = 0.f;
+  textParameters.ellipsisEnabled = true;
+  textParameters.markupEnabled = true;
+
+
+  CircularTextData data =
+  {
+      "IncrementAngle",
+      "",
+      textParameters,
+      embeddedItems,
+      true
+  };
+
+  if( !CircularRenderTest( data ) )
+  {
+    tet_result(TET_FAIL);
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+
+
+int UtcDaliTextCircularMarkup(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextCircularMarkup");
+
+  Dali::Toolkit::DevelText::RendererParameters textParameters;
+  textParameters.text = "Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World";
+  textParameters.horizontalAlignment = "center";
+  textParameters.verticalAlignment = "center";
+  textParameters.circularAlignment = "center";
+  textParameters.fontFamily = "SamsungUI";
+  textParameters.fontWeight = "";
+  textParameters.fontWidth = "";
+  textParameters.fontSlant = "";
+  textParameters.layout = "circular";
+  textParameters.textColor = Color::BLACK;
+  textParameters.fontSize = 25.f;
+  textParameters.textWidth = 360u;
+  textParameters.textHeight = 360u;
+  textParameters.radius = 180u;
+  textParameters.beginAngle = 15.f;
+  textParameters.incrementAngle = 360.f;
+  textParameters.ellipsisEnabled = true;
+  textParameters.markupEnabled = false;
+
+  CircularTextData data =
+  {
+      "Markup",
+      "",
+      textParameters,
+      embeddedItems,
+      true
+  };
+
+  if( !CircularRenderTest( data ) )
+  {
+    tet_result(TET_FAIL);
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextCircularFont(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextCircularFont");
+
+  const std::string image1 = "<item 'width'=26 'height'=26 'url'='" + TEST_IMAGE_FILE_NAME1 + "'/>";
+  const std::string image2 = "<item 'width'=26 'height'=26/>";
+
+  Dali::Toolkit::DevelText::RendererParameters textParameters;
+  textParameters.text = "Hello " + image1 + " world " + image2 + " this " + image1 + " is " + image2 + " a " + image1 + " demo " + image2 + " of " + image1 + " circular " + image2 + " text " + image1 + " width " + image2 + " icons.";
+  textParameters.horizontalAlignment = "center";
+  textParameters.verticalAlignment = "center";
+  textParameters.circularAlignment = "center";
+  textParameters.fontFamily = "SamsungUI";
+  textParameters.fontWeight = "thin";
+  textParameters.fontWidth = "condensed";
+  textParameters.fontSlant = "normal";
+  textParameters.layout = "circular";
+  textParameters.textColor = Color::BLACK;
+  textParameters.fontSize = 25.f;
+  textParameters.textWidth = 360u;
+  textParameters.textHeight = 360u;
+  textParameters.radius = 180u;
+  textParameters.beginAngle = 15.f;
+  textParameters.incrementAngle = 360.f;
+  textParameters.ellipsisEnabled = true;
+  textParameters.markupEnabled = true;
+
+  CircularTextData data =
+  {
+      "Font",
+      "",
+      textParameters,
+      embeddedItems,
+      true
+  };
+
+  if( !CircularRenderTest( data ) )
+  {
+    tet_result(TET_FAIL);
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextCircularAlignment(void)
+{
+
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextCircularAlignment");
+
+  const std::string image1 = "<item 'width'=26 'height'=26 'url'='" + TEST_IMAGE_FILE_NAME1 + "'/>";
+  const std::string image2 = "<item 'width'=26 'height'=26/>";
+
+  Dali::Toolkit::DevelText::RendererParameters textParameters;
+  textParameters.text = "Hello " + image1 + " world " + image2 + " this " + image1 + " is " + image2 + " a " + image1 + " demo " + image2 + " of " + image1 + " circular " + image2 + " text " + image1 + " width " + image2 + " icons.";
+  textParameters.horizontalAlignment = "center";
+  textParameters.verticalAlignment = "center";
+  textParameters.circularAlignment = "center";
+  textParameters.fontFamily = "SamsungUI";
+  textParameters.fontWeight = "";
+  textParameters.fontWidth = "";
+  textParameters.fontSlant = "";
+  textParameters.layout = "circular";
+  textParameters.textColor = Color::BLACK;
+  textParameters.fontSize = 25.f;
+  textParameters.textWidth = 360u;
+  textParameters.textHeight = 360u;
+  textParameters.radius = 180u;
+  textParameters.beginAngle = 15.f;
+  textParameters.incrementAngle = 360.f;
+  textParameters.ellipsisEnabled = true;
+  textParameters.markupEnabled = true;
+
+  CircularTextData data =
+  {
+      "Alignment",
+      "",
+      textParameters,
+      embeddedItems,
+      true
+  };
+
+  if( !CircularRenderTest( data ) )
+  {
+    tet_result(TET_FAIL);
+  }
+
+  textParameters.horizontalAlignment = "begin";
+  textParameters.verticalAlignment = "top";
+  textParameters.circularAlignment = "begin";
+
+  if( !CircularRenderTest( data ) )
+  {
+    tet_result(TET_FAIL);
+  }
+
+  textParameters.horizontalAlignment = "end";
+  textParameters.verticalAlignment = "bottom";
+  textParameters.circularAlignment = "end";
+
+  if( !CircularRenderTest( data ) )
+  {
+    tet_result(TET_FAIL);
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextCircularRTL(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextCircularRTL");
+
+  const std::string image1 = "<item 'width'=26 'height'=26 'url'='" + TEST_IMAGE_FILE_NAME1 + "'/>";
+  const std::string image2 = "<item 'width'=26 'height'=26/>";
+
+  Dali::Toolkit::DevelText::RendererParameters textParameters;
+  textParameters.text = "مرحبا بالعالم" + image1 + " hello world " + image2 + " this " + image1 + " is " + image2 + " a " + image1 + " demo " + image2 + " of " + image1 + " circular " + image2 + " text " + image1 + " width " + image2 + " icons.";
+  textParameters.horizontalAlignment = "center";
+  textParameters.verticalAlignment = "center";
+  textParameters.circularAlignment = "center";
+  textParameters.fontFamily = "SamsungUI";
+  textParameters.fontWeight = "";
+  textParameters.fontWidth = "";
+  textParameters.fontSlant = "";
+  textParameters.layout = "circular";
+  textParameters.textColor = Color::BLACK;
+  textParameters.fontSize = 25.f;
+  textParameters.textWidth = 360u;
+  textParameters.textHeight = 360u;
+  textParameters.radius = 180u;
+  textParameters.beginAngle = 15.f;
+  textParameters.incrementAngle = 360.f;
+  textParameters.ellipsisEnabled = true;
+  textParameters.markupEnabled = true;
+
+  CircularTextData data =
+  {
+      "RTL",
+      "",
+      textParameters,
+      embeddedItems,
+      true
+  };
+
+  if( !CircularRenderTest( data ) )
+  {
+    tet_result(TET_FAIL);
+  }
+
+  textParameters.circularAlignment = "begin";
+  if( !CircularRenderTest( data ) )
+  {
+    tet_result(TET_FAIL);
+  }
+
+  textParameters.circularAlignment = "end";
+  if( !CircularRenderTest( data ) )
+  {
+    tet_result(TET_FAIL);
+  }
+
+  textParameters.text = "שלום עולם مرحبا بالعالم שלום עולם مرحبا بالعالم שלום עולם مرحبا بالعالم";
+  textParameters.layout = "singleLine";
+  textParameters.horizontalAlignment = "end";
+  textParameters.fontSize = 90.f;
+  if( !CircularRenderTest( data ) )
+  {
+    tet_result(TET_FAIL);
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextCircularN(void)
+{
+
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextCircularN");
+
+  const std::string image1 = "<item 'width'=26 'height'=26 'url'='" + TEST_IMAGE_FILE_NAME1 + "'/>";
+  const std::string image2 = "<item 'width'=26 'height'=26/>";
+
+  Dali::Toolkit::DevelText::RendererParameters textParameters;
+  textParameters.text = "hello " + image1 + " world " + image2 + " this " + image1 + " is " + image2 + " a " + image1 + " demo " + image2 + " of " + image1 + " circular " + image2 + " text " + image1 + " width " + image2 + " icons.";
+  textParameters.horizontalAlignment = "center";
+  textParameters.verticalAlignment = "center";
+  textParameters.circularAlignment = "center";
+  textParameters.fontFamily = "SamsungUI";
+  textParameters.fontWeight = "";
+  textParameters.fontWidth = "";
+  textParameters.fontSlant = "";
+  textParameters.layout = "singleLine";
+  textParameters.textColor = Color::BLACK;
+  textParameters.fontSize = 25.f;
+  textParameters.textWidth = 360u;
+  textParameters.textHeight = 360u;
+  textParameters.radius = 180u;
+  textParameters.beginAngle = 15.f;
+  textParameters.incrementAngle = 360.f;
+  textParameters.ellipsisEnabled = true;
+  textParameters.markupEnabled = true;
+
+  CircularTextData data =
+  {
+      "singleLine",
+      "",
+      textParameters,
+      embeddedItems,
+      true
+  };
+
+  if( !CircularRenderTest( data ) )
+  {
+    tet_result(TET_FAIL);
+  }
+
+  textParameters.verticalAlignment = "top";
+  if( !CircularRenderTest( data ) )
+  {
+    tet_result(TET_FAIL);
+  }
+
+  textParameters.verticalAlignment = "bottom";
+  if( !CircularRenderTest( data ) )
+  {
+    tet_result(TET_FAIL);
+  }
+
+  textParameters.textWidth = 90u;
+  if( !CircularRenderTest( data ) )
+  {
+    tet_result(TET_FAIL);
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextCircularBlend(void)
+{
+  tet_infoline(" UtcDaliTextCircularN");
+
+  ToolkitTestApplication application;
+  Stage stage = Stage::GetCurrent();
+  stage.SetBackgroundColor( Color::WHITE );
+  stage.SetBackgroundColor( Vector4( 0.04f, 0.345f, 0.392f, 1.0f ) );
+
+
+  const std::string image1 = "<item 'width'=26 'height'=26 'url'='" + TEST_IMAGE_FILE_NAME1 + "'/>";
+  const std::string image2 = "<item 'width'=26 'height'=26/>";
+
+  Dali::Toolkit::DevelText::RendererParameters textParameters;
+  textParameters.text = "hello " + image1 + " world " + image2 + " this " + image1 + " is " + image2 + " a " + image1 + " demo " + image2 + " of " + image1 + " circular " + image2 + " text " + image1 + " width " + image2 + " icons.";
+  textParameters.horizontalAlignment = "center";
+  textParameters.verticalAlignment = "center";
+  textParameters.circularAlignment = "center";
+  textParameters.fontFamily = "SamsungUI";
+  textParameters.fontWeight = "";
+  textParameters.fontWidth = "";
+  textParameters.fontSlant = "";
+  textParameters.layout = "circular";
+  textParameters.textColor = Color::BLACK;
+  textParameters.fontSize = 25.f;
+  textParameters.textWidth = 360u;
+  textParameters.textHeight = 360u;
+  textParameters.radius = 180u;
+  textParameters.beginAngle = 15.f;
+  textParameters.incrementAngle = 360.f;
+  textParameters.ellipsisEnabled = true;
+  textParameters.markupEnabled = true;
+
+  CircularTextData data =
+  {
+      "blend",
+      "",
+      textParameters,
+      embeddedItems,
+      false
+  };
+
+  if( !CircularRenderTest( data ) )
+  {
+    tet_result(TET_FAIL);
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextCircularEllipsis(void)
+{
+  tet_infoline(" UtcDaliTextCircularEllipsis");
+
+  ToolkitTestApplication application;
+
+  const std::string image1 = "<item 'width'=26 'height'=26 'url'='" + TEST_IMAGE_FILE_NAME1 + "'/>";
+  const std::string image2 = "<item 'width'=26 'height'=26/>";
+
+  Dali::Toolkit::DevelText::RendererParameters textParameters;
+  textParameters.text = "hello " + image1 + " world " + image2 + " this " + image1 + " is " + image2 + " a " + image1 + " demo " + image2 + " of " + image1 + " circular " + image2 + " text " + image1 + " width " + image2 + " icons.";
+  textParameters.horizontalAlignment = "center";
+  textParameters.verticalAlignment = "center";
+  textParameters.circularAlignment = "center";
+  textParameters.fontFamily = "SamsungUI";
+  textParameters.fontWeight = "";
+  textParameters.fontWidth = "";
+  textParameters.fontSlant = "";
+  textParameters.layout = "circular";
+  textParameters.textColor = Color::BLACK;
+  textParameters.fontSize = 25.f;
+  textParameters.textWidth = 360u;
+  textParameters.textHeight = 360u;
+  textParameters.radius = 180u;
+  textParameters.beginAngle = 15.f;
+  textParameters.incrementAngle = 360.f;
+  textParameters.ellipsisEnabled = false;
+  textParameters.markupEnabled = true;
+
+  CircularTextData data =
+  {
+      "ellipsis",
+      "",
+      textParameters,
+      embeddedItems,
+      true
+  };
+
+  if( !CircularRenderTest( data ) )
+  {
+    tet_result(TET_FAIL);
+  }
+
+  textParameters.layout = "singleLine";
+  textParameters.textHeight = 50u;
+  textParameters.ellipsisEnabled = true;
+
+  if( !CircularRenderTest( data ) )
+  {
+    tet_result(TET_FAIL);
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextCircularEmoji(void)
+{
+  tet_infoline(" UtcDaliTextCircularEmoji");
+
+  ToolkitTestApplication application;
+
+  const std::string image1 = "<item 'width'=26 'height'=26 'url'='" + TEST_IMAGE_FILE_NAME1 + "'/>";
+  const std::string image2 = "<item 'width'=26 'height'=26/>";
+
+  Dali::Toolkit::DevelText::RendererParameters textParameters;
+  textParameters.text = "<font family='BreezeColorEmoji' size='60'>\xF0\x9F\x98\x81 \xF0\x9F\x98\x82 \xF0\x9F\x98\x83 \xF0\x9F\x98\x84</font>";
+  textParameters.horizontalAlignment = "center";
+  textParameters.verticalAlignment = "center";
+  textParameters.circularAlignment = "center";
+  textParameters.fontFamily = "SamsungUI";
+  textParameters.fontWeight = "";
+  textParameters.fontWidth = "";
+  textParameters.fontSlant = "";
+  textParameters.layout = "circular";
+  textParameters.textColor = Color::BLACK;
+  textParameters.fontSize = 25.f;
+  textParameters.textWidth = 360u;
+  textParameters.textHeight = 360u;
+  textParameters.radius = 180u;
+  textParameters.beginAngle = 15.f;
+  textParameters.incrementAngle = 360.f;
+  textParameters.ellipsisEnabled = true;
+  textParameters.markupEnabled = true;
+
+  CircularTextData data =
+  {
+      "Emoji",
+      "",
+      textParameters,
+      embeddedItems,
+      true
+  };
+
+  if( !CircularRenderTest( data ) )
+  {
+    tet_result(TET_FAIL);
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextUpdateBufferFormatCheck(void)
+{
+  tet_infoline(" UtcDaliTextUpdateBufferFormatCheck");
+  ToolkitTestApplication application;
+
+  Devel::PixelBuffer srcBuffer = Devel::PixelBuffer::New( 10, 10, Pixel::RGBA8888 );
+  Devel::PixelBuffer dstBuffer = Devel::PixelBuffer::New( 10, 10, Pixel::A8 );
+
+  Dali::Toolkit::DevelText::UpdateBuffer(srcBuffer, dstBuffer, 0, 0, true);
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextCircularTextColor(void)
+{
+  tet_infoline(" UtcDaliTextCircularTextColor");
+
+  ToolkitTestApplication application;
+
+  const std::string image1 = "<item 'width'=26 'height'=26 'url'='" + TEST_IMAGE_FILE_NAME1 + "'/>";
+  const std::string image2 = "<item 'width'=26 'height'=26/>";
+
+  Dali::Toolkit::DevelText::RendererParameters textParameters;
+  textParameters.text = "hello " + image1 + " <color value='blue'>world</color> " + image2 + " this " + image1 + " is " + image2 + " a " + image1 + " demo " + image2 + " of " + image1 + " circular " + image2 + " text " + image1 + " width " + image2 + " icons.";
+  textParameters.horizontalAlignment = "center";
+  textParameters.verticalAlignment = "center";
+  textParameters.circularAlignment = "center";
+  textParameters.fontFamily = "SamsungUI";
+  textParameters.fontWeight = "";
+  textParameters.fontWidth = "";
+  textParameters.fontSlant = "";
+  textParameters.layout = "circular";
+  textParameters.textColor = Color::BLACK;
+  textParameters.fontSize = 25.f;
+  textParameters.textWidth = 360u;
+  textParameters.textHeight = 360u;
+  textParameters.radius = 180u;
+  textParameters.beginAngle = 15.f;
+  textParameters.incrementAngle = 360.f;
+  textParameters.ellipsisEnabled = true;
+  textParameters.markupEnabled = true;
+
+  CircularTextData data =
+  {
+      "textColor",
+      "",
+      textParameters,
+      embeddedItems,
+      true
+  };
+
+  if( !CircularRenderTest( data ) )
+  {
+    tet_result(TET_FAIL);
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextCircularColorBlend(void)
+{
+  tet_infoline(" UtcDaliTextCircularColorBlend");
+
+  ToolkitTestApplication application;
+
+  const std::string image1 = "<item 'width'=26 'height'=26 'url'='" + TEST_IMAGE_FILE_NAME1 +  "' 'color-blending'=multiply/>";
+  const std::string image2 = "<item 'width'=26 'height'=26/>";
+
+  Dali::Toolkit::DevelText::RendererParameters textParameters;
+  textParameters.text = "hello " + image1 + " world " + image2 + " this " + image1 + " is " + image2 + " a " + image1 + " demo " + image2 + " of " + image1 + " circular " + image2 + " text " + image1 + " width " + image2 + " icons.";
+  textParameters.horizontalAlignment = "center";
+  textParameters.verticalAlignment = "center";
+  textParameters.circularAlignment = "center";
+  textParameters.fontFamily = "SamsungUI";
+  textParameters.fontWeight = "";
+  textParameters.fontWidth = "";
+  textParameters.fontSlant = "";
+  textParameters.layout = "circular";
+  textParameters.textColor = Color::BLACK;
+  textParameters.fontSize = 25.f;
+  textParameters.textWidth = 360u;
+  textParameters.textHeight = 360u;
+  textParameters.radius = 180u;
+  textParameters.beginAngle = 15.f;
+  textParameters.incrementAngle = 360.f;
+  textParameters.ellipsisEnabled = true;
+  textParameters.markupEnabled = true;
+
+  CircularTextData data =
+  {
+      "colorBlend",
+      "",
+      textParameters,
+      embeddedItems,
+      true
+  };
+
+  if( !CircularRenderTest( data ) )
+  {
+    tet_result(TET_FAIL);
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
index 66b7149..5538586 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -574,8 +574,8 @@ int UtcDaliTextControllerSetGetLineSpacingProperty(void)
   // single line, line spacing = 0px
   {
     const float EXPECTED_SPACING = 0.0f;
-    const Vector2 EXPECTED_LAYOUT_SIZE( 326.0f, 19.0f);
-    const Vector3 EXPECTED_NATURAL_SIZE( 326.0f, 20.0f, 0.0f );
+    const Vector2 EXPECTED_LAYOUT_SIZE( 343.0f, 19.0f);
+    const Vector3 EXPECTED_NATURAL_SIZE( 344.0f, 20.0f, 0.0f );
 
     controller->SetText(textSingle);
     controller->Relayout(size);
@@ -593,8 +593,8 @@ int UtcDaliTextControllerSetGetLineSpacingProperty(void)
   // single line, line spacing = 20px
   {
     const float EXPECTED_SPACING = 20.0f;
-    const Vector2 EXPECTED_LAYOUT_SIZE( 326.0f, 19.0f );
-    const Vector3 EXPECTED_NATURAL_SIZE( 326.0f, 40.0f, 0.0f );
+    const Vector2 EXPECTED_LAYOUT_SIZE( 343.0f, 19.0f );
+    const Vector3 EXPECTED_NATURAL_SIZE( 344.0f, 40.0f, 0.0f );
 
     controller->SetText(textSingle);
     controller->Relayout(size);
@@ -613,8 +613,8 @@ int UtcDaliTextControllerSetGetLineSpacingProperty(void)
   // multi-line, line spacing = 0px
   {
     const float EXPECTED_SPACING = 0.0f;
-    const Vector2 EXPECTED_LAYOUT_SIZE( 318.0f, 39.0f );
-    const Vector3 EXPECTED_NATURAL_SIZE( 116.0f, 58.0f, 0.0f );
+    const Vector2 EXPECTED_LAYOUT_SIZE( 333.0f, 39.0f );
+    const Vector3 EXPECTED_NATURAL_SIZE( 120.0f, 58.0f, 0.0f );
 
     controller->SetText(textMulti);
     controller->Relayout(size);
@@ -633,8 +633,8 @@ int UtcDaliTextControllerSetGetLineSpacingProperty(void)
   // multi-line, line spacing = 20px
   {
     const float EXPECTED_SPACING = 20.0f;
-    const Vector2 EXPECTED_LAYOUT_SIZE( 115.0f, 57.0f );
-    const Vector3 EXPECTED_NATURAL_SIZE( 116.0f, 118.0f, 0.0f );
+    const Vector2 EXPECTED_LAYOUT_SIZE( 119.0f, 57.0f );
+    const Vector3 EXPECTED_NATURAL_SIZE( 120.0f, 118.0f, 0.0f );
 
     controller->SetText(textMulti);
     controller->Relayout(size);
@@ -653,8 +653,8 @@ int UtcDaliTextControllerSetGetLineSpacingProperty(void)
   // multi-line, line spacing = 30px
   {
     const float EXPECTED_SPACING = 30.0f;
-    const Vector2 EXPECTED_LAYOUT_SIZE( 115.0f, 117.0f );
-    const Vector3 EXPECTED_NATURAL_SIZE( 116.0f, 148.0f, 0.0f );
+    const Vector2 EXPECTED_LAYOUT_SIZE( 119.0f, 117.0f );
+    const Vector3 EXPECTED_NATURAL_SIZE( 120.0f, 148.0f, 0.0f );
 
     controller->SetText(textMulti);
     controller->Relayout(size);
index 8b9bffd..249c728 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -717,7 +717,7 @@ int UtcDaliTextLayoutSmallTextArea02(void)
   Vector<FontDescriptionRun> fontDescriptionRuns;
   fontDescriptionRuns.PushBack( fontDescriptionRun );
   Size textArea(1.f, 1.f);
-  Size layoutSize(80.f, 20.f);
+  Size layoutSize(80.f, 19.f);
   float positions[] = { 1.f, -12.f, 11.f, -9.f, 20.f, -13.f, 24.f, -13.f, 27.f, -9.f, 36.f, -0.f, 40.f, -9.f, 51.f, -9.f, 61.f, -9.f, 67.f, -13.f, 70.f, -13.f };
   struct LineRun line =
   {
@@ -725,7 +725,7 @@ int UtcDaliTextLayoutSmallTextArea02(void)
     { 0u, 11u },
     80.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -801,7 +801,7 @@ int UtcDaliTextLayoutMultilineText01(void)
   fontDescriptionRuns.PushBack( fontDescriptionRun1 );
   fontDescriptionRuns.PushBack( fontDescriptionRun2 );
   Size textArea(100.f, 300.f);
-  Size layoutSize(95.f, 97.f);
+  Size layoutSize(95.f, 95.f);
   float positions[] =
   {
     1.f, -12.f, 11.f,  -9.f, 20.f, -13.f, 24.f, -13.f, 27.f, -9.f, 36.f,  -0.f, 40.f, -9.f, 51.f,  -9.f, 61.f, -9.f, 67.f, -13.f, 70.f, -13.f, 79.f, -0.f,
@@ -816,7 +816,7 @@ int UtcDaliTextLayoutMultilineText01(void)
     { 0u, 12u },
     80.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -829,7 +829,7 @@ int UtcDaliTextLayoutMultilineText01(void)
     { 12u, 6u },
     43.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -1000,7 +1000,7 @@ int UtcDaliTextLayoutMultilineText02(void)
   fontDescriptionRuns.PushBack( fontDescriptionRun4 );
   fontDescriptionRuns.PushBack( fontDescriptionRun5 );
   Size textArea(100.f, 300.f);
-  Size layoutSize(80.f, 120.f);
+  Size layoutSize(80.f, 114.f);
   float positions[] =
   {
     1.f, -12.f, 11.f,  -9.f, 20.f, -13.f, 24.f, -13.f, 27.f, -9.f, 36.f,  -0.f, 40.f,  -9.f, 51.f,  -9.f, 61.f,  -9.f, 67.f, -13.f, 70.f, -13.f, 79.f, -0.f,
@@ -1016,7 +1016,7 @@ int UtcDaliTextLayoutMultilineText02(void)
     { 0u, 12u },
     80.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -1029,7 +1029,7 @@ int UtcDaliTextLayoutMultilineText02(void)
     { 12u, 10u },
     76.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -1042,7 +1042,7 @@ int UtcDaliTextLayoutMultilineText02(void)
     { 22u, 6u },
     34.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -1055,7 +1055,7 @@ int UtcDaliTextLayoutMultilineText02(void)
     { 28u, 10u },
     67.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -1068,7 +1068,7 @@ int UtcDaliTextLayoutMultilineText02(void)
     { 38u, 12u },
     78.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -1081,7 +1081,7 @@ int UtcDaliTextLayoutMultilineText02(void)
     { 50u, 5u },
     43.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -1150,7 +1150,7 @@ int UtcDaliTextLayoutMultilineText03(void)
   Vector<FontDescriptionRun> fontDescriptionRuns;
   fontDescriptionRuns.PushBack( fontDescriptionRun );
   Size textArea(100.f, 300.f);
-  Size layoutSize(96.f, 60.f);
+  Size layoutSize(96.f, 57.f);
   float positions[] =
   {
     1.f, -12.f, 11.f, -9.f, 20.f, -13.f, 24.f, -13.f, 27.f,  -9.f, 36.f,  -9.f, 47.f, -9.f, 57.f, -9.f, 63.f, -13.f, 66.f, -13.f, 75.f, -13.f, 84.f,  -9.f,
@@ -1163,7 +1163,7 @@ int UtcDaliTextLayoutMultilineText03(void)
     { 0u, 12u },
     93.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -1176,7 +1176,7 @@ int UtcDaliTextLayoutMultilineText03(void)
     { 12u, 12u },
     96.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -1189,7 +1189,7 @@ int UtcDaliTextLayoutMultilineText03(void)
     { 24u, 5u },
     43.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -1254,7 +1254,7 @@ int UtcDaliTextLayoutMultilineText04(void)
   Vector<FontDescriptionRun> fontDescriptionRuns;
   fontDescriptionRuns.PushBack( fontDescriptionRun );
   Size textArea(100.f, 300.f);
-  Size layoutSize(83.f, 40.f);
+  Size layoutSize(83.f, 38.f);
   float positions[] =
   {
     1.f, -12.f, 11.f, -9.f, 20.f, -13.f, 24.f, -13.f, 27.f, -9.f, 36.f, -0.f, 40.f, -9.f, 51.f, -9.f, 61.f, -9.f, 67.f, -13.f, 70.f, -13.f, 79.f, -2.f, 82.f, -12.f
@@ -1265,7 +1265,7 @@ int UtcDaliTextLayoutMultilineText04(void)
     { 0u, 13u },
     83.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     false,
@@ -1277,7 +1277,7 @@ int UtcDaliTextLayoutMultilineText04(void)
     { 13u, 0u },
     0.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -1368,19 +1368,19 @@ int UtcDaliTextLayoutMultilineText05(void)
   fontDescriptionRuns.PushBack( fontDescriptionRun2 );
   fontDescriptionRuns.PushBack( fontDescriptionRun3 );
   Size textArea(100.f, 300.f);
-  Size layoutSize(88.f, 53.f);
+  Size layoutSize(89.f, 51.f);
   float positions[] =
   {
-    1.f, -12.f, 11.f, -9.f, 20.f, -13.f, 24.f, -13.f, 27.f, -9.f, 36.f, -0.f, 40.f, -14.f, 59.f, -9.f, 69.f, -9.f, 75.f, -13.f, 78.f, -13.f, 87.f, -0.f,
+    1.f, -12.f, 11.f, -9.f, 20.f, -13.f, 24.f, -13.f, 27.f, -9.f, 36.f, -0.f, 40.f, -14.f, 60.f, -9.f, 70.f, -9.f, 76.f, -13.f, 79.f, -13.f, 88.f, -0.f,
     0.f, -13.f,  9.f, -9.f, 18.f,  -9.f, 30.f,  -9.f, 39.f, -2.f
   };
   struct LineRun line0 =
   {
     { 0u, 12u },
     { 0u, 12u },
-    88.f,
+    89.f,
     25.f,
-    -8.f,
+    -7.f,
     4.f,
     0.f,
     0.f,
@@ -1393,7 +1393,7 @@ int UtcDaliTextLayoutMultilineText05(void)
     { 12u, 5u },
     43.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -1683,7 +1683,7 @@ int UtcDaliTextUpdateLayout01(void)
   fontDescriptionRuns.PushBack( fontDescriptionRun16 );
   fontDescriptionRuns.PushBack( fontDescriptionRun17 );
   Size textArea(100.f, 300.f);
-  Size layoutSize(92.f, 380.f);
+  Size layoutSize(92.f, 361.f);
   float positions[] =
   {
     1.f, -12.f, 11.f, -9.f, 20.f, -13.f, 24.f, -13.f, 27.f, -9.f, 36.f, -0.f, 40.f, -9.f, 51.f, -9.f, 61.f, -9.f, 67.f, -13.f, 70.f, -13.f, 79.f, -0.f,
@@ -1712,7 +1712,7 @@ int UtcDaliTextUpdateLayout01(void)
     { 0u, 12u },
     80.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -1725,7 +1725,7 @@ int UtcDaliTextUpdateLayout01(void)
     { 12u, 10u },
     76.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -1738,7 +1738,7 @@ int UtcDaliTextUpdateLayout01(void)
     { 22u, 6u },
     34.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -1751,7 +1751,7 @@ int UtcDaliTextUpdateLayout01(void)
     { 28u, 20u },
     92.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -1764,7 +1764,7 @@ int UtcDaliTextUpdateLayout01(void)
     { 48u, 11u },
     76.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -1777,7 +1777,7 @@ int UtcDaliTextUpdateLayout01(void)
     { 59u, 5u },
     31.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -1790,7 +1790,7 @@ int UtcDaliTextUpdateLayout01(void)
     { 64u, 10u },
     67.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -1803,7 +1803,7 @@ int UtcDaliTextUpdateLayout01(void)
     { 74u, 12u },
     78.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     1.f,
     0.f,
@@ -1816,7 +1816,7 @@ int UtcDaliTextUpdateLayout01(void)
     { 86u, 6u },
     43.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -1829,7 +1829,7 @@ int UtcDaliTextUpdateLayout01(void)
     { 92u, 12u },
     78.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -1842,7 +1842,7 @@ int UtcDaliTextUpdateLayout01(void)
     { 104u, 19u },
     90.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -1855,7 +1855,7 @@ int UtcDaliTextUpdateLayout01(void)
     { 123u, 5u },
     31.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -1868,7 +1868,7 @@ int UtcDaliTextUpdateLayout01(void)
     { 128u, 12u },
     80.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -1881,7 +1881,7 @@ int UtcDaliTextUpdateLayout01(void)
     { 140u, 10u },
     76.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -1894,7 +1894,7 @@ int UtcDaliTextUpdateLayout01(void)
     { 150u, 6u },
     34.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -1907,7 +1907,7 @@ int UtcDaliTextUpdateLayout01(void)
     { 156u, 10u },
     67.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -1920,7 +1920,7 @@ int UtcDaliTextUpdateLayout01(void)
     { 166u, 12u },
     79.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -1933,7 +1933,7 @@ int UtcDaliTextUpdateLayout01(void)
     { 178u, 14u },
     55.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -1946,7 +1946,7 @@ int UtcDaliTextUpdateLayout01(void)
     { 192u, 0u },
     0.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -2258,7 +2258,7 @@ int UtcDaliTextUpdateLayout02(void)
   fontDescriptionRuns.PushBack( fontDescriptionRun16 );
   fontDescriptionRuns.PushBack( fontDescriptionRun17 );
   Size textArea(100.f, 300.f);
-  Size layoutSize(92.f, 380.f);
+  Size layoutSize(92.f, 361.f);
   float positions[] =
   {
     1.f, -12.f, 11.f, -9.f, 20.f, -13.f, 24.f, -13.f, 27.f, -9.f, 36.f, -0.f, 40.f, -9.f, 51.f, -9.f, 61.f, -9.f, 67.f, -13.f, 70.f, -13.f, 79.f, -0.f,
@@ -2287,7 +2287,7 @@ int UtcDaliTextUpdateLayout02(void)
     { 0u, 12u },
     80.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -2300,7 +2300,7 @@ int UtcDaliTextUpdateLayout02(void)
     { 12u, 10u },
     76.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -2313,7 +2313,7 @@ int UtcDaliTextUpdateLayout02(void)
     { 22u, 6u },
     34.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -2326,7 +2326,7 @@ int UtcDaliTextUpdateLayout02(void)
     { 28u, 20u },
     92.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -2339,7 +2339,7 @@ int UtcDaliTextUpdateLayout02(void)
     { 48u, 11u },
     76.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -2352,7 +2352,7 @@ int UtcDaliTextUpdateLayout02(void)
     { 59u, 5u },
     31.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -2365,7 +2365,7 @@ int UtcDaliTextUpdateLayout02(void)
     { 64u, 10u },
     67.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -2378,7 +2378,7 @@ int UtcDaliTextUpdateLayout02(void)
     { 74u, 12u },
     78.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     1.f,
     0.f,
@@ -2391,7 +2391,7 @@ int UtcDaliTextUpdateLayout02(void)
     { 86u, 6u },
     43.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -2404,7 +2404,7 @@ int UtcDaliTextUpdateLayout02(void)
     { 92u, 12u },
     78.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -2417,7 +2417,7 @@ int UtcDaliTextUpdateLayout02(void)
     { 104u, 19u },
     90.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -2430,7 +2430,7 @@ int UtcDaliTextUpdateLayout02(void)
     { 123u, 5u },
     31.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -2443,7 +2443,7 @@ int UtcDaliTextUpdateLayout02(void)
     { 128u, 12u },
     80.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -2456,7 +2456,7 @@ int UtcDaliTextUpdateLayout02(void)
     { 140u, 10u },
     76.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -2469,7 +2469,7 @@ int UtcDaliTextUpdateLayout02(void)
     { 150u, 6u },
     34.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -2482,7 +2482,7 @@ int UtcDaliTextUpdateLayout02(void)
     { 156u, 10u },
     67.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -2495,7 +2495,7 @@ int UtcDaliTextUpdateLayout02(void)
     { 166u, 12u },
     79.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -2508,7 +2508,7 @@ int UtcDaliTextUpdateLayout02(void)
     { 178u, 14u },
     55.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -2521,7 +2521,7 @@ int UtcDaliTextUpdateLayout02(void)
     { 192u, 0u },
     0.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -2833,7 +2833,7 @@ int UtcDaliTextUpdateLayout03(void)
   fontDescriptionRuns.PushBack( fontDescriptionRun16 );
   fontDescriptionRuns.PushBack( fontDescriptionRun17 );
   Size textArea(100.f, 300.f);
-  Size layoutSize(92.f, 380.f);
+  Size layoutSize(92.f, 361.f);
   float positions[] =
   {
     1.f, -12.f, 11.f, -9.f, 20.f, -13.f, 24.f, -13.f, 27.f, -9.f, 36.f, -0.f, 40.f, -9.f, 51.f, -9.f, 61.f, -9.f, 67.f, -13.f, 70.f, -13.f, 79.f, -0.f,
@@ -2862,7 +2862,7 @@ int UtcDaliTextUpdateLayout03(void)
     { 0u, 12u },
     80.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -2875,7 +2875,7 @@ int UtcDaliTextUpdateLayout03(void)
     { 12u, 10u },
     76.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -2888,7 +2888,7 @@ int UtcDaliTextUpdateLayout03(void)
     { 22u, 6u },
     34.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -2901,7 +2901,7 @@ int UtcDaliTextUpdateLayout03(void)
     { 28u, 20u },
     92.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -2914,7 +2914,7 @@ int UtcDaliTextUpdateLayout03(void)
     { 48u, 11u },
     76.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -2927,7 +2927,7 @@ int UtcDaliTextUpdateLayout03(void)
     { 59u, 5u },
     31.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -2940,7 +2940,7 @@ int UtcDaliTextUpdateLayout03(void)
     { 64u, 10u },
     67.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -2953,7 +2953,7 @@ int UtcDaliTextUpdateLayout03(void)
     { 74u, 12u },
     78.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     1.f,
     0.f,
@@ -2966,7 +2966,7 @@ int UtcDaliTextUpdateLayout03(void)
     { 86u, 6u },
     43.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -2979,7 +2979,7 @@ int UtcDaliTextUpdateLayout03(void)
     { 92u, 12u },
     78.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -2992,7 +2992,7 @@ int UtcDaliTextUpdateLayout03(void)
     { 104u, 19u },
     90.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -3005,7 +3005,7 @@ int UtcDaliTextUpdateLayout03(void)
     { 123u, 5u },
     31.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -3018,7 +3018,7 @@ int UtcDaliTextUpdateLayout03(void)
     { 128u, 12u },
     80.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -3031,7 +3031,7 @@ int UtcDaliTextUpdateLayout03(void)
     { 140u, 10u },
     76.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -3044,7 +3044,7 @@ int UtcDaliTextUpdateLayout03(void)
     { 150u, 6u },
     34.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -3057,7 +3057,7 @@ int UtcDaliTextUpdateLayout03(void)
     { 156u, 10u },
     67.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -3070,7 +3070,7 @@ int UtcDaliTextUpdateLayout03(void)
     { 166u, 12u },
     79.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -3083,7 +3083,7 @@ int UtcDaliTextUpdateLayout03(void)
     { 178u, 14u },
     55.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -3096,7 +3096,7 @@ int UtcDaliTextUpdateLayout03(void)
     { 192u, 0u },
     0.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -3188,7 +3188,7 @@ int UtcDaliTextLayoutEllipsis01(void)
     { 0u, 13u },
     93.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -3204,7 +3204,7 @@ int UtcDaliTextLayoutEllipsis01(void)
   };
 
   Size textArea( 100.f, 50.f );
-  Size layoutSize( 100.f, 20.f );
+  Size layoutSize( 100.f, 19.f );
 
   LayoutTextData data =
   {
@@ -3265,7 +3265,7 @@ int UtcDaliTextLayoutEllipsis02(void)
     { 0u, 12u },
     80.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -3278,7 +3278,7 @@ int UtcDaliTextLayoutEllipsis02(void)
     { 12u, 12u },
     93.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -3296,7 +3296,7 @@ int UtcDaliTextLayoutEllipsis02(void)
   };
 
   Size textArea( 100.f, 50.f );
-  Size layoutSize( 100.f, 40.f );
+  Size layoutSize( 100.f, 38.f );
 
   LayoutTextData data =
   {
@@ -3423,7 +3423,7 @@ int UtcDaliTextLayoutEllipsis03(void)
     { 0u, 16u },
     95.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
@@ -3439,7 +3439,7 @@ int UtcDaliTextLayoutEllipsis03(void)
   };
 
   Size textArea( 100.f, 50.f );
-  Size layoutSize( 100.f, 20.f );
+  Size layoutSize( 100.f, 19.f );
 
   LayoutTextData data =
   {
@@ -3566,7 +3566,7 @@ int UtcDaliTextLayoutEllipsis04(void)
     { 0u, 16u },
     96.f,
     15.f,
-    -5.f,
+    -4.f,
     3.f,
     0.f,
     0.f,
@@ -3579,7 +3579,7 @@ int UtcDaliTextLayoutEllipsis04(void)
     { 16u, 18u },
     97.f,
     15.f,
-    -5.f,
+    -4.f,
     4.f,
     0.f,
     0.f,
@@ -3597,7 +3597,7 @@ int UtcDaliTextLayoutEllipsis04(void)
   };
 
   Size textArea( 100.f, 50.f );
-  Size layoutSize( 100.f, 40.f );
+  Size layoutSize( 100.f, 38.f );
 
   LayoutTextData data =
   {
@@ -3656,12 +3656,12 @@ int UtcDaliTextLayoutEllipsis05(void)
     { 0u, 11u },
     80.f,
     15.f,
-    -5.f,
+    -4.f,
     0.f,
     0.f,
     0.f,
     false,
-    true
+    false
   };
   Vector<LineRun> lines;
   lines.PushBack( line01 );
@@ -3672,7 +3672,7 @@ int UtcDaliTextLayoutEllipsis05(void)
   };
 
   Size textArea( 100.f, 19.f );
-  Size layoutSize( 100.f, 20.f );
+  Size layoutSize( 80.f, 19.f );
 
   LayoutTextData data =
   {
index 7007170..779eb56 100755 (executable)
@@ -36,6 +36,7 @@ using namespace Text;
 
 namespace
 {
+
   ///////////////////////////////////////////////////////////
 
   struct TokenComparisonData
@@ -182,9 +183,20 @@ namespace
 
     Vector<ColorRun> colorRuns;
     Vector<FontDescriptionRun> fontRuns;
-    MarkupProcessData markupProcessData( colorRuns, fontRuns );
+    Vector<EmbeddedItem> items;
+    MarkupProcessData markupProcessData( colorRuns, fontRuns, items );
     ProcessMarkupString( data.xHTMLEntityString, markupProcessData );
 
+    for( Vector<EmbeddedItem>::Iterator it = items.Begin(),
+           endIt = items.End();
+         it != endIt;
+         ++it )
+    {
+      EmbeddedItem& item = *it;
+      delete[] item.url;
+    }
+    items.Clear();
+
     if( markupProcessData.markupProcessedText != data.expectedString )
     {
       std::cout << "  different output string : " << markupProcessData.markupProcessedText << ", expected : " << data.expectedString << " " << std::endl;
old mode 100644 (file)
new mode 100755 (executable)
index b5bf653..9a7bf3f
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -55,8 +55,8 @@ struct GlyphInfoData
   float yBearing;    ///< The distance from the baseline to the topmost border of the glyph
   float advance;     ///< The distance to move the cursor for this glyph
   float scaleFactor; ///< The scaling applied (fixed-size fonts only)
-  bool softwareItalic; ///< Whether glyph needs software support to draw italic style
-  bool softwareBold;   ///< Whether glyph needs software support to draw bold style
+  bool isItalicRequired; ///< Whether the italic style is required.
+  bool isBoldRequired;   ///< Whether the bold style is required.
 };
 
 bool IsEqualGlyph ( const GlyphInfoData& glyphData, const GlyphInfo& glyph )
@@ -93,11 +93,11 @@ bool IsEqualGlyph ( const GlyphInfoData& glyphData, const GlyphInfo& glyph )
   {
     return false;
   }
-  if( glyphData.softwareItalic != glyph.softwareItalic )
+  if( glyphData.isItalicRequired != glyph.isItalicRequired )
   {
     return false;
   }
-  if( glyphData.softwareBold != glyph.softwareBold )
+  if( glyphData.isBoldRequired != glyph.isBoldRequired )
   {
     return false;
   }
@@ -328,18 +328,18 @@ int UtcDaliTextShape(void)
 
   struct GlyphInfoData glyphs04[] =
   {
-    { 2u, 160u, 0.f, 0.f, 0.f, 0.f,  5.f, 0.f },
-    { 2u, 123u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
-    { 2u, 153u, 0.f, 0.f, 0.f, 0.f,  5.f, 0.f },
-    { 2u, 160u, 0.f, 0.f, 0.f, 0.f,  5.f, 0.f },
-    { 2u, 150u, 0.f, 0.f, 0.f, 0.f, 14.f, 0.f },
-    { 2u, 153u, 0.f, 0.f, 0.f, 0.f,  5.f, 0.f },
-    { 2u, 160u, 0.f, 0.f, 0.f, 0.f,  5.f, 0.f },
-    { 2u, 151u, 0.f, 0.f, 0.f, 0.f, 12.f, 0.f },
-    { 2u, 153u, 0.f, 0.f, 0.f, 0.f,  5.f, 0.f },
-    { 2u, 160u, 0.f, 0.f, 0.f, 0.f,  5.f, 0.f },
-    { 2u, 147u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
-    { 2u, 153u, 0.f, 0.f, 0.f, 0.f,  5.f, 0.f },
+    { 2u, 1733u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
+    { 2u, 1693u, 0.f, 0.f, 0.f, 0.f, 13.f, 0.f },
+    { 2u, 1725u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
+    { 2u, 1733u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
+    { 2u, 1721u, 0.f, 0.f, 0.f, 0.f, 20.f, 0.f },
+    { 2u, 1725u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
+    { 2u, 1733u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
+    { 2u, 1722u, 0.f, 0.f, 0.f, 0.f, 18.f, 0.f },
+    { 2u, 1725u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
+    { 2u, 1733u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
+    { 2u, 1718u, 0.f, 0.f, 0.f, 0.f, 14.f, 0.f },
+    { 2u, 1725u, 0.f, 0.f, 0.f, 0.f,  8.f, 0.f },
   };
 
   CharacterIndex characterIndices04[] = { 0u, 0u, 0u, 2u, 2u, 2u, 4u, 4u, 4u, 6u, 6u, 6u };
@@ -382,7 +382,7 @@ int UtcDaliTextShape(void)
     { 1u,  3u, 0.f, 0.f, 0.f, 0.f,  5.f, 0.f },
     { 1u, 71u, 0.f, 0.f, 0.f, 0.f, 10.f, 0.f },
     { 1u, 72u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
-    { 1u, 5034u, 0.f, 0.f, 0.f, 0.f, 10.f, 0.f },
+    { 1u, 5039u, 0.f, 0.f, 0.f, 0.f, 10.f, 0.f },
     { 1u, 81u, 0.f, 0.f, 0.f, 0.f, 10.f, 0.f },
     { 1u, 76u, 0.f, 0.f, 0.f, 0.f,  4.f, 0.f },
     { 1u, 72u, 0.f, 0.f, 0.f, 0.f,  9.f, 0.f },
@@ -551,15 +551,15 @@ int UtcDaliTextSoftwareStyling(void)
 
   struct GlyphInfoData glyphs01[] =
   {
-    { 2u, 14750u, 0.f, 0.f, 0.f, 0.f, 16.f, 0.f, true, true },
-    { 2u, 9802u, 0.f, 0.f, 0.f, 0.f,  16.f, 0.f, true, true },
-    { 2u, 12811u, 0.f, 0.f, 0.f, 0.f,  16.f, 0.f, true, true },
+    { 2u, 21154u, 0.f, 0.f, 0.f, 0.f, 16.f, 0.f, true, true },
+    { 2u, 12298, 0.f, 0.f, 0.f, 0.f, 16.f, 0.f, true, true },
+    { 2u, 17828u, 0.f, 0.f, 0.f, 0.f, 16.f, 0.f, true, true },
   };
   struct GlyphInfoData glyphs02[] =
   {
-    { 2u, 14750u, 0.f, 0.f, 0.f, 0.f, 16.f, 0.f, false, false },
-    { 2u, 9802u, 0.f, 0.f, 0.f, 0.f,  16.f, 0.f, false, true },
-    { 2u, 12811u, 0.f, 0.f, 0.f, 0.f,  16.f, 0.f, true, false },
+    { 2u, 21154u, 0.f, 0.f, 0.f, 0.f, 16.f, 0.f, false, false },
+    { 2u, 12298, 0.f, 0.f, 0.f, 0.f, 16.f, 0.f, false, true },
+    { 2u, 17828u, 0.f, 0.f, 0.f, 0.f, 16.f, 0.f, true,  false },
   };
 
   CharacterIndex characterIndices[] = { 0u, 1u, 2u };
@@ -691,4 +691,4 @@ int UtcDaliTextSoftwareStyling(void)
 
   tet_result(TET_PASS);
   END_TEST;
-}
\ No newline at end of file
+}
old mode 100644 (file)
new mode 100755 (executable)
index 49d36e0..66e2682
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -49,14 +49,14 @@ const char* LOREM_IPSUM = "Lorem ipsum dolor sit amet, aeque definiebas ea mei,
   "Aliquip sanctůs delicáta quí ěá, et natum aliquam est?\n"
   "Asšúm sapěret usu ůť.\n"
   "Síť ut apeirián laboramúš percipitur, sůas hařum ín éos?\n";
-const Vector2 LOREM_SCROLL_POSITION( 0.f, -208.f );
-const Length LOREM_NUMBER_OF_LINES = 32u;
+const Vector2 LOREM_SCROLL_POSITION( 0.f, -265.f );
+const Length LOREM_NUMBER_OF_LINES = 35u;
 const Length LOREM_NUMBER_OF_LINES_ELIDED = 21u;
 const Length LOREM_NUMBER_OF_GLYPHS = 632;
-const Length LOREM_NUMBER_OF_GLYPHS_ELIDED = 397u;
+const Length LOREM_NUMBER_OF_GLYPHS_ELIDED = 395u;
 
 // The expected layout size for UtcDaliTextViewModelGetLayoutSize
-const Size LAYOUT_SIZE( 190.f, 48.f );
+const Size LAYOUT_SIZE( 197.f, 45.f );
 
 // The expected color indices for UtcDaliTextViewModelGetColors
 const ColorIndex COLOR_INDICES[] = { 0u, 0u, 0u, 0u, 0u, 0u, 1u, 1u, 1u, 2u, 2u, 2u, 2u, 2u, 1u, 1u, 1u, 1u, 1u, 3u, 1u, 1u, 1u, 0u, 0u, 0u, 0u };
@@ -583,13 +583,13 @@ int UtcDaliTextViewModelElideText02(void)
   Size textSize00( 100.f, 100.f );
 
   Size textSize01( 80.f, 100.f );
-  float positions01[] = { 0.f, 9.f, 17.f, 27.f, 35.f, 37.f, 46.f, 56.f };
+  float positions01[] = { 0.f, 8.f, 16.f, 26.f, 33.f, 41.f, 45.f, 54.f, 64.0f };
 
   Size textSize02( 80.f, 100.f );
-  float positions02[] = { 72.f, 63.f, 54.f, 50.f, 43.f, 38.f, 30.f, 11.f };
+  float positions02[] = { 72.f, 63.f, 54.f, 50.f, 43.f, 38.f, 30.f, 23.0f };
 
   Size textSize03( 80.f, 100.f );
-  float positions03[] = { 77.f, 76.f, 71.f, 62.f, 59.f, 52.f, 47.f, 42.f, 39.f, 35.f, 32.f, 13.f };
+  float positions03[] = { 78.f, 73.f, 70.f, 65.f, 57.f, 55.f, 51.f, 50.f, 45.f, 35.f, 32.f, 24.f, 21.f };
 
   Size textSize04( 80.f, 10.f );
   float positions04[] = { 2.f };
@@ -609,7 +609,7 @@ int UtcDaliTextViewModelElideText02(void)
       "<font family='TizenSans'>Lorem ipsum dolor sit amet, aeque definiebas ea mei, posse iracundia ne cum.</font>",
       textSize01,
       5u,
-      42u,
+      37u,
       positions01
     },
     {
@@ -625,7 +625,7 @@ int UtcDaliTextViewModelElideText02(void)
       "<font family='TizenSansArabic'>عل النفط ديسمبر الإمداد بال, بين وترك شعار هو. لمّ من المبرمة النفط بالسيطرة, أم يتم تحرّك وبغطاء, عدم في لإعادة وإقامة رجوعهم.</font>",
       textSize03,
       5u,
-      79u,
+      74u,
       positions03
     },
     {
index d72bf17..823c7bb 100644 (file)
 
 using namespace Dali::Toolkit::Internal;
 
+
+void utc_dali_toolkit_texture_manager_startup(void)
+{
+  setenv( "LOG_TEXTURE_MANAGER", "3", 1 );
+  test_return_value = TET_UNDEF;
+}
+
+void utc_dali_toolkit_texture_manager_cleanup(void)
+{
+  test_return_value = TET_PASS;
+}
+
 class TestObserver : public Dali::Toolkit::TextureUploadObserver
 {
 public:
index 6b38451..bc765c7 100644 (file)
@@ -37,6 +37,7 @@ LIST(APPEND TC_SOURCES
    ../dali-toolkit/dali-toolkit-test-utils/toolkit-virtual-keyboard.cpp
    ../dali-toolkit/dali-toolkit-test-utils/dummy-control.cpp
    ../dali-toolkit/dali-toolkit-test-utils/dali-test-suite-utils.cpp
+   ../dali-toolkit/dali-toolkit-test-utils/dali-toolkit-test-suite-utils.cpp
    ../dali-toolkit/dali-toolkit-test-utils/test-animation-data.cpp
    ../dali-toolkit/dali-toolkit-test-utils/test-button.cpp
    ../dali-toolkit/dali-toolkit-test-utils/test-application.cpp
@@ -45,6 +46,7 @@ LIST(APPEND TC_SOURCES
    ../dali-toolkit/dali-toolkit-test-utils/test-gl-abstraction.cpp
    ../dali-toolkit/dali-toolkit-test-utils/test-gl-sync-abstraction.cpp
    ../dali-toolkit/dali-toolkit-test-utils/test-render-controller.cpp
+   ../dali-toolkit/dali-toolkit-test-utils/test-render-surface.cpp
    ../dali-toolkit/dali-toolkit-test-utils/test-trace-call-stack.cpp
    ../dali-toolkit/dali-toolkit-test-utils/test-native-image.cpp
 )
index e9ff79a..6f50e82 100644 (file)
@@ -26,6 +26,7 @@ LIST(APPEND TC_SOURCES
    ../dali-toolkit/dali-toolkit-test-utils/toolkit-timer.cpp
    ../dali-toolkit/dali-toolkit-test-utils/toolkit-tts-player.cpp
    ../dali-toolkit/dali-toolkit-test-utils/dali-test-suite-utils.cpp
+   ../dali-toolkit/dali-toolkit-test-utils/dali-toolkit-test-suite-utils.cpp
    ../dali-toolkit/dali-toolkit-test-utils/dummy-control.cpp
    ../dali-toolkit/dali-toolkit-test-utils/mesh-builder.cpp
    ../dali-toolkit/dali-toolkit-test-utils/test-actor-utils.cpp
@@ -38,6 +39,7 @@ LIST(APPEND TC_SOURCES
    ../dali-toolkit/dali-toolkit-test-utils/test-gl-sync-abstraction.cpp
    ../dali-toolkit/dali-toolkit-test-utils/test-platform-abstraction.cpp
    ../dali-toolkit/dali-toolkit-test-utils/test-render-controller.cpp
+   ../dali-toolkit/dali-toolkit-test-utils/test-render-surface.cpp
    ../dali-toolkit/dali-toolkit-test-utils/test-trace-call-stack.cpp
    ../dali-toolkit/dali-toolkit-test-utils/test-native-image.cpp
 )
index bd9848f..678a4ae 100755 (executable)
@@ -104,6 +104,7 @@ LIST(APPEND TC_SOURCES
   dali-toolkit-test-utils/toolkit-web-engine.cpp
   dali-toolkit-test-utils/toolkit-trigger-event-factory.cpp
   dali-toolkit-test-utils/dali-test-suite-utils.cpp
+  dali-toolkit-test-utils/dali-toolkit-test-suite-utils.cpp
   dali-toolkit-test-utils/dummy-control.cpp
   dali-toolkit-test-utils/layout-utils.cpp
   dali-toolkit-test-utils/mesh-builder.cpp
@@ -117,6 +118,7 @@ LIST(APPEND TC_SOURCES
   dali-toolkit-test-utils/test-gl-sync-abstraction.cpp
   dali-toolkit-test-utils/test-platform-abstraction.cpp
   dali-toolkit-test-utils/test-render-controller.cpp
+  dali-toolkit-test-utils/test-render-surface.cpp
   dali-toolkit-test-utils/test-trace-call-stack.cpp
   dali-toolkit-test-utils/test-native-image.cpp
 )
diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dali-toolkit-test-suite-utils.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dali-toolkit-test-suite-utils.cpp
new file mode 100644 (file)
index 0000000..94c9530
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "dali-toolkit-test-suite-utils.h"
+
+
+std::ostream& operator<<( std::ostream& ostream, Dali::Toolkit::Visual::ResourceStatus status )
+{
+  switch(status)
+  {
+    case Dali::Toolkit::Visual::ResourceStatus::PREPARING:
+    {
+      ostream << "PREPARING";
+      break;
+    }
+    case Dali::Toolkit::Visual::ResourceStatus::READY:
+    {
+      ostream << "READY";
+      break;
+    }
+    case Dali::Toolkit::Visual::ResourceStatus::FAILED:
+    {
+      ostream << "FAILED";
+      break;
+    }
+  }
+  return ostream;
+}
index 32dac4b..013d2c6 100644 (file)
@@ -2,7 +2,7 @@
 #define __DALI_TOOLKIT_TEST_SUITE_UTILS_H__
 
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  *
  */
 
+#include <iostream>
+#include <dali-toolkit/public-api/visuals/visual-properties.h>
+
+// Put any toolkit specific operators for DALI_TEST_CHECK template here, before dali-test-suite-utils.h.
+
+std::ostream& operator<<( std::ostream& ostream, Dali::Toolkit::Visual::ResourceStatus status );
+
 // INTERNAL INCLUDES
 
 #include <dali-test-suite-utils.h>
index c953f50..1562d27 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -54,8 +54,6 @@ void TestApplication::Initialize()
                                         Integration::StencilBufferAvailable::TRUE );
 
   mCore->ContextCreated();
-  mCore->SurfaceResized( mSurfaceWidth, mSurfaceHeight );
-  mCore->SetDpi( mDpi.x, mDpi.y );
 
   Dali::Integration::Log::LogFunction logFunction(&TestApplication::LogMessage);
   Dali::Integration::Log::InstallLogFunction(logFunction);
@@ -65,12 +63,22 @@ void TestApplication::Initialize()
 
   Dali::Integration::Trace::LogContext( true, "Test" );
 
+  mRenderSurface = new TestRenderSurface( Dali::PositionSize( 0, 0, mSurfaceWidth, mSurfaceHeight ) );
+  mScene = Dali::Integration::Scene::New( Vector2( static_cast<float>( mSurfaceWidth ), static_cast<float>( mSurfaceHeight ) ) );
+  mScene.SetSurface( *mRenderSurface );
+
+  mScene.SetDpi( Vector2( static_cast<float>( mDpi.x ), static_cast<float>( mDpi.y ) ) );
+
+  mCore->SurfaceResized( mRenderSurface );
+
   mCore->SceneCreated();
+  mCore->Initialize();
 }
 
 TestApplication::~TestApplication()
 {
   Dali::Integration::Log::UninstallLogFunction();
+  delete mRenderSurface;
   delete mCore;
 }
 
@@ -149,19 +157,6 @@ void TestApplication::SendNotification()
   mCore->ProcessEvents();
 }
 
-void TestApplication::SetSurfaceWidth( uint32_t width, uint32_t height )
-{
-  mSurfaceWidth = width;
-  mSurfaceHeight = height;
-
-  mCore->SurfaceResized( mSurfaceWidth, mSurfaceHeight );
-}
-
-void TestApplication::SetTopMargin( uint32_t margin )
-{
-  mCore->SetTopMargin( margin );
-}
-
 void TestApplication::DoUpdate( uint32_t intervalMilliseconds, const char* location )
 {
   if( GetUpdateStatus() == 0 &&
index d1e042d..fc2929c 100644 (file)
@@ -2,7 +2,7 @@
 #define __DALI_TEST_APPLICATION_H__
 
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include "test-gl-sync-abstraction.h"
 #include "test-gl-abstraction.h"
 #include "test-render-controller.h"
+#include "test-render-surface.h"
 #include <dali/public-api/common/dali-common.h>
 #include <dali/integration-api/resource-policies.h>
 #include <dali/integration-api/trace.h>
+#include <dali/integration-api/scene.h>
 
 namespace Dali
 {
@@ -69,8 +71,6 @@ public:
   TestGestureManager& GetGestureManager();
   void ProcessEvent(const Integration::Event& event);
   void SendNotification();
-  void SetSurfaceWidth( uint32_t width, unsigned height );
-  void SetTopMargin( uint32_t margin );
   bool Render( uint32_t intervalMilliseconds = DEFAULT_RENDER_INTERVAL, const char* location=NULL );
   uint32_t GetUpdateStatus();
   bool UpdateOnly( uint32_t intervalMilliseconds = DEFAULT_RENDER_INTERVAL );
@@ -83,6 +83,11 @@ public:
     mLoggingEnabled = enabled;
   }
 
+  Integration::Scene GetScene() const
+  {
+    return mScene;
+  }
+
 private:
   void DoUpdate( uint32_t intervalMilliseconds, const char* location=NULL );
 
@@ -92,11 +97,13 @@ protected:
   TestGlAbstraction         mGlAbstraction;
   TestGlSyncAbstraction     mGlSyncAbstraction;
   TestGestureManager        mGestureManager;
+  TestRenderSurface*        mRenderSurface;
 
   Integration::UpdateStatus mStatus;
   Integration::RenderStatus mRenderStatus;
 
   Integration::Core* mCore;
+  Dali::Integration::Scene mScene;
 
   uint32_t mSurfaceWidth;
   uint32_t mSurfaceHeight;
diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-render-surface.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-render-surface.cpp
new file mode 100644 (file)
index 0000000..332d77e
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "test-render-surface.h"
+
+namespace Dali
+{
+
+TestRenderSurface::TestRenderSurface( Dali::PositionSize positionSize )
+: mPositionSize( positionSize ),
+  mBackgroundColor()
+{
+}
+
+TestRenderSurface::~TestRenderSurface()
+{
+}
+
+Dali::PositionSize TestRenderSurface::GetPositionSize() const
+{
+  return mPositionSize;
+};
+
+void TestRenderSurface::GetDpi( unsigned int& dpiHorizontal, unsigned int& dpiVertical )
+{
+  dpiHorizontal = dpiVertical = 96;
+};
+
+void TestRenderSurface::InitializeGraphics()
+{
+}
+
+void TestRenderSurface::CreateSurface()
+{
+}
+
+void TestRenderSurface::DestroySurface()
+{
+}
+
+bool TestRenderSurface::ReplaceGraphicsSurface()
+{
+  return false;
+}
+
+void TestRenderSurface::MoveResize( Dali::PositionSize positionSize )
+{
+  mPositionSize = positionSize;
+}
+
+void TestRenderSurface::StartRender()
+{
+}
+
+bool TestRenderSurface::PreRender( bool resizingSurface )
+{
+  return true;
+}
+
+void TestRenderSurface::PostRender( bool renderToFbo, bool replacingSurface, bool resizingSurface )
+{
+}
+
+void TestRenderSurface::StopRender()
+{
+}
+
+void TestRenderSurface::ReleaseLock()
+{
+}
+
+Dali::Integration::RenderSurface::Type TestRenderSurface::GetSurfaceType()
+{
+  return WINDOW_RENDER_SURFACE;
+}
+
+void TestRenderSurface::MakeContextCurrent()
+{
+}
+
+Integration::DepthBufferAvailable TestRenderSurface::GetDepthBufferRequired()
+{
+  return Integration::DepthBufferAvailable::TRUE;
+}
+
+Integration::StencilBufferAvailable TestRenderSurface::GetStencilBufferRequired()
+{
+  return Integration::StencilBufferAvailable::TRUE;
+}
+
+void TestRenderSurface::SetBackgroundColor( Vector4 color )
+{
+  mBackgroundColor = color;
+}
+
+Vector4 TestRenderSurface::GetBackgroundColor()
+{
+  return mBackgroundColor;
+}
+
+} // Namespace dali
diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-render-surface.h b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-render-surface.h
new file mode 100644 (file)
index 0000000..fba89c2
--- /dev/null
@@ -0,0 +1,155 @@
+#ifndef TEST_REENDER_SURFACE_H
+#define TEST_REENDER_SURFACE_H
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/public-api/common/dali-common.h>
+#include <dali/integration-api/render-surface.h>
+
+namespace Dali
+{
+
+/**
+ * Concrete implementation of the RenderSurface class.
+ */
+class DALI_CORE_API TestRenderSurface : public Dali::Integration::RenderSurface
+{
+public:
+
+  /**
+   * @copydoc Dali::Integration::RenderSurface::RenderSurface
+   */
+  TestRenderSurface( Dali::PositionSize positionSize );
+
+  /**
+   * @copydoc Dali::Integration::RenderSurface::~RenderSurface
+   */
+  virtual ~TestRenderSurface();
+
+  /**
+   * @copydoc Dali::Integration::RenderSurface::GetPositionSize
+   */
+  virtual Dali::PositionSize GetPositionSize() const;
+
+  /**
+   * @copydoc Dali::Integration::RenderSurface::GetDpi
+   */
+  virtual void GetDpi( unsigned int& dpiHorizontal, unsigned int& dpiVertical );
+
+  /**
+   * @copydoc Dali::Integration::RenderSurface::InitializeGraphics
+   */
+  virtual void InitializeGraphics();
+
+  /**
+   * @copydoc Dali::Integration::RenderSurface::CreateSurface
+   */
+  virtual void CreateSurface();
+
+  /**
+   * @copydoc Dali::Integration::RenderSurface::DestroySurface
+   */
+  virtual void DestroySurface();
+
+  /**
+   * @copydoc Dali::Integration::RenderSurface::ReplaceGraphicsSurface
+   */
+  virtual bool ReplaceGraphicsSurface();
+
+  /**
+   * @copydoc Dali::Integration::RenderSurface::MoveResize
+   */
+  virtual void MoveResize( Dali::PositionSize positionSize );
+
+  /**
+   * @copydoc Dali::Integration::RenderSurface::StartRender
+   */
+  virtual void StartRender();
+
+  /**
+   * @copydoc Dali::Integration::RenderSurface::PreRender
+   */
+  virtual bool PreRender( bool resizingSurface );
+
+  /**
+   * @copydoc Dali::Integration::RenderSurface::PostRender
+   */
+  virtual void PostRender( bool renderToFbo, bool replacingSurface, bool resizingSurface );
+
+  /**
+   * @copydoc Dali::Integration::RenderSurface::StopRender
+   */
+  virtual void StopRender();
+
+  /**
+   * @copydoc Dali::Integration::RenderSurface::ReleaseLock
+   */
+  virtual void ReleaseLock();
+
+  /**
+   * @copydoc Dali::Integration::RenderSurface::GetSurfaceType
+   */
+  virtual Dali::Integration::RenderSurface::Type GetSurfaceType();
+
+  /**
+   * @copydoc Dali::Integration::RenderSurface::MakeContextCurrent
+   */
+  virtual void MakeContextCurrent();
+
+  /**
+   * @copydoc Dali::Integration::RenderSurface::GetDepthBufferRequired
+   */
+  virtual Integration::DepthBufferAvailable GetDepthBufferRequired();
+
+  /**
+   * @copydoc Dali::Integration::RenderSurface::GetStencilBufferRequired
+   */
+  virtual Integration::StencilBufferAvailable GetStencilBufferRequired();
+
+  /**
+   * @copydoc Dali::Integration::RenderSurface::SetBackgroundColor
+   */
+  virtual void SetBackgroundColor( Vector4 color );
+
+  /**
+   * @copydoc Dali::Integration::RenderSurface::GetBackgroundColor
+   */
+  virtual Vector4 GetBackgroundColor();
+
+private:
+
+  /**
+   * @brief Undefined copy constructor. RenderSurface cannot be copied
+   */
+  TestRenderSurface( const TestRenderSurface& rhs );
+
+  /**
+   * @brief Undefined assignment operator. RenderSurface cannot be copied
+   */
+  TestRenderSurface& operator=( const TestRenderSurface& rhs );
+
+private:
+
+  Dali::PositionSize mPositionSize;
+  Vector4 mBackgroundColor;                                     ///< The background color of the surface
+};
+
+} // Dali
+
+#endif
index 8cd215b..a4b0d87 100644 (file)
@@ -88,7 +88,6 @@ public:
   bool HandleActionReadFromTopEvent();
   bool HandleActionReadFromNextEvent();
   bool HandleActionZoomEvent();
-  bool HandleActionReadIndicatorInformationEvent();
   bool HandleActionReadPauseResumeEvent();
   bool HandleActionStartStopEvent();
 
@@ -385,15 +384,6 @@ bool AccessibilityAdaptor::HandleActionZoomEvent()
   return false;
 }
 
-bool AccessibilityAdaptor::HandleActionReadIndicatorInformationEvent()
-{
-  if( mActionHandler )
-  {
-    return mActionHandler->AccessibilityActionReadIndicatorInformation();
-  }
-  return false;
-}
-
 bool AccessibilityAdaptor::HandleActionReadPauseResumeEvent()
 {
   if( mActionHandler )
@@ -590,11 +580,6 @@ bool AccessibilityAdaptor::HandleActionZoomEvent()
   return Internal::Adaptor::GetImplementation(*this).HandleActionZoomEvent();
 }
 
-bool AccessibilityAdaptor::HandleActionReadIndicatorInformationEvent()
-{
-  return Internal::Adaptor::GetImplementation(*this).HandleActionReadIndicatorInformationEvent();
-}
-
 bool AccessibilityAdaptor::HandleActionReadPauseResumeEvent()
 {
   return Internal::Adaptor::GetImplementation(*this).HandleActionReadPauseResumeEvent();
index ee60af1..902167c 100644 (file)
@@ -18,7 +18,7 @@
  *
  */
 
-#include <dali/integration-api/adaptors/render-surface.h>
+#include <dali/integration-api/adaptors/render-surface-interface.h>
 
 namespace Dali
 {
@@ -45,40 +45,6 @@ class GlAbstraction;
 
 } // namespace Integration
 
-class TestRenderSurface : public RenderSurface
-{
-public:
-  virtual PositionSize GetPositionSize() const { PositionSize size; return size; }
-
-  virtual void GetDpi( unsigned int& dpiHorizontal, unsigned int& dpiVertical ) { dpiHorizontal = dpiVertical = 96; }
-
-  virtual void InitializeGraphics( Dali::Internal::Adaptor::GraphicsInterface& graphics, Dali::DisplayConnection& displayConnection ) {};
-
-  virtual void CreateSurface() {}
-
-  virtual void DestroySurface() {}
-
-  virtual bool ReplaceGraphicsSurface() { return false; }
-
-  virtual void MoveResize( Dali::PositionSize positionSize ) {}
-
-  virtual void SetViewMode( ViewMode viewMode ) {}
-
-  virtual void StartRender() {}
-
-  virtual bool PreRender( bool resizingSurface ) { return false; }
-
-  virtual void PostRender( bool renderToFbo, bool replacingSurface, bool resizingSurface ) {}
-
-  virtual void StopRender() {}
-
-  virtual void ReleaseLock() {}
-
-  virtual void SetThreadSynchronization( ThreadSynchronizationInterface& threadSynchronization ) {}
-
-  virtual RenderSurface::Type GetSurfaceType() { return RenderSurface::WINDOW_RENDER_SURFACE; }
-};
-
 namespace Internal
 {
 namespace Adaptor
@@ -92,7 +58,7 @@ public:
   ~Adaptor();
 
 public:
-  static Dali::RenderSurface& GetSurface();
+  static Dali::RenderSurfaceInterface& GetSurface();
   static Dali::Adaptor::AdaptorSignalType& AdaptorSignal();
   static bool mAvailable;
   static Vector<CallbackBase*> mCallbacks;
index dcf0560..5d6cf4e 100644 (file)
@@ -23,6 +23,7 @@
 #include <toolkit-adaptor-impl.h>
 #include <dali/integration-api/debug.h>
 #include <test-application.h>
+#include <test-render-surface.h>
 
 namespace Dali
 {
@@ -42,9 +43,9 @@ Dali::Adaptor& Adaptor::Get()
   return *adaptor;
 }
 
-Dali::RenderSurface& Adaptor::GetSurface()
+Dali::RenderSurfaceInterface& Adaptor::GetSurface()
 {
-  Dali::RenderSurface *renderSurface = new Dali::TestRenderSurface;
+  Dali::RenderSurfaceInterface* renderSurface = reinterpret_cast <Dali::RenderSurfaceInterface*>( new Dali::TestRenderSurface( Dali::PositionSize( 0, 0, 480, 800 ) ) );
   return *renderSurface;
 }
 
@@ -67,12 +68,12 @@ Adaptor& Adaptor::New( Window window, Configuration::ContextLoss configuration )
   return Internal::Adaptor::Adaptor::Get();
 }
 
-Adaptor& Adaptor::New( Any nativeWindow, const Dali::RenderSurface& surface )
+Adaptor& Adaptor::New( Any nativeWindow, const Dali::RenderSurfaceInterface& surface )
 {
   return Internal::Adaptor::Adaptor::Get();
 }
 
-Adaptor& Adaptor::New( Any nativeWindow, const Dali::RenderSurface& surface, Configuration::ContextLoss configuration )
+Adaptor& Adaptor::New( Any nativeWindow, const Dali::RenderSurfaceInterface& surface, Configuration::ContextLoss configuration )
 {
   return Internal::Adaptor::Adaptor::Get();
 }
@@ -129,7 +130,7 @@ void Adaptor::RemoveIdle( CallbackBase* callback )
   }
 }
 
-void Adaptor::ReplaceSurface( Any nativeWindow, Dali::RenderSurface& surface )
+void Adaptor::ReplaceSurface( Any nativeWindow, Dali::RenderSurfaceInterface& surface )
 {
 }
 
@@ -143,7 +144,7 @@ Adaptor::AdaptorSignalType& Adaptor::LanguageChangedSignal()
   return Internal::Adaptor::Adaptor::AdaptorSignal();
 }
 
-RenderSurface& Adaptor::GetSurface()
+Dali::RenderSurfaceInterface& Adaptor::GetSurface()
 {
   return Internal::Adaptor::Adaptor::GetSurface();
 }
index 5b8a324..02f3d8f 100644 (file)
@@ -77,7 +77,7 @@ bool EventThreadCallback::WaitingForTrigger()
   struct timespec now;
   clock_gettime( CLOCK_REALTIME, &now );
   if( now.tv_nsec < 999900000 ) // 999, 900, 000
-    now.tv_nsec += 100000;
+    now.tv_nsec += 1000;
   else
   {
     now.tv_sec += 1;
@@ -124,6 +124,10 @@ bool WaitForEventThreadTrigger( int triggerCount, int timeoutInSeconds )
           Dali::CallbackBase::Execute( *callback );
           triggerCount--;
         }
+        if( triggerCount <= 0 )
+        {
+          break;
+        }
       }
     }
     clock_gettime( CLOCK_REALTIME, &now );
index e8c2e8d..7ba5ca4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 #include <dali/public-api/object/base-object.h>
 #include <dali/devel-api/common/map-wrapper.h>
 #include <dali/public-api/signals/dali-signal.h>
+#include <dali/integration-api/processor-interface.h>
 
 namespace Dali
 {
index 6a42d9c..869bbc2 100755 (executable)
@@ -64,11 +64,16 @@ public:
   {
   }
 
-  uint32_t GetTotalFrameNumber()
+  uint32_t GetTotalFrameNumber() const
   {
     return 5;
   }
 
+  float GetFrameRate() const
+  {
+    return 60.0f;
+  }
+
 public:
 
   std::string mUrl;
@@ -157,10 +162,15 @@ void VectorAnimationRenderer::Render( uint32_t frameNumber )
   Internal::Adaptor::GetImplementation( *this ).Render( frameNumber );
 }
 
-uint32_t VectorAnimationRenderer::GetTotalFrameNumber()
+uint32_t VectorAnimationRenderer::GetTotalFrameNumber() const
 {
   return Internal::Adaptor::GetImplementation( *this ).GetTotalFrameNumber();
 }
 
+float VectorAnimationRenderer::GetFrameRate() const
+{
+  return Internal::Adaptor::GetImplementation( *this ).GetFrameRate();
+}
+
 } // namespace Dali;
 
index 395e8f9..98ea974 100644 (file)
@@ -69,7 +69,6 @@ int UtcDaliLayouting_AbsoluteLayoutAssignment(void)
   END_TEST;
 }
 
-
 int UtcDaliLayouting_AbsoluteLayout01(void)
 {
   ToolkitTestApplication application;
@@ -120,3 +119,43 @@ int UtcDaliLayouting_AbsoluteLayout01(void)
 
   END_TEST;
 }
+
+int UtcDaliLayouting_AbsoluteLayout_SetPosition(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliLayouting_AbsoluteLayout_GetWorldPosition - Testing WorldPosition");
+
+  Stage stage = Stage::GetCurrent();
+
+  Dali::Toolkit::Control layoutControl = Dali::Toolkit::Control::New();
+  layoutControl.SetName("AsoluteLayout");
+  layoutControl.SetAnchorPoint( Dali::AnchorPoint::CENTER );
+  layoutControl.SetParentOrigin( Dali::ParentOrigin::CENTER );
+
+  Dali::Toolkit::AbsoluteLayout absoluteLayout = Dali::Toolkit::AbsoluteLayout::New();
+  Dali::Toolkit::DevelControl::SetLayout( layoutControl, absoluteLayout );
+
+  stage.GetRootLayer().Add( layoutControl );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render(0);
+
+  Dali::Toolkit::Control control = Dali::Toolkit::Control::New();
+  control.SetSize( 100.0f, 100.0f );
+  control.SetParentOrigin( ParentOrigin::CENTER );
+  control.SetAnchorPoint( AnchorPoint::CENTER );
+  Vector3 parentPosition( 1.0f, 2.0f, 3.0f );
+  control.SetPosition( parentPosition );
+
+  layoutControl.Add( control );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render(0);
+
+  // The value of z should not be zero
+  DALI_TEST_EQUALS( control.GetCurrentPosition(), parentPosition, TEST_LOCATION );
+
+  END_TEST;
+}
index 23200c0..2044f1e 100644 (file)
@@ -2131,30 +2131,6 @@ int UtcDaliAccessibilityManagerActionZoomSignalN(void)
   END_TEST;
 }
 
-int UtcDaliAccessibilityManagerActionReadIndicatorInformationSignalP(void)
-{
-  ToolkitTestApplication application;
-  tet_infoline( " UtcDaliAccessibilityManagerActionReadIndicatorInformationSignalP" );
-
-  AccessibilityManagerSignalHandler callback;
-
-  Dali::AccessibilityAdaptor accAdaptor = Dali::AccessibilityAdaptor::Get();
-  Test::AccessibilityAdaptor::SetEnabled( accAdaptor, true );
-  accAdaptor.HandleActionEnableEvent();
-
-  AccessibilityManager manager = AccessibilityManager::Get();
-  DALI_TEST_CHECK( manager );
-
-  manager.ActionReadIndicatorInformationSignal().Connect( &callback, &AccessibilityManagerSignalHandler::Callback );
-
-  Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
-  accessibilityAdaptor.HandleActionReadIndicatorInformationEvent();
-
-  DALI_TEST_EQUALS( callback.GetCalls(), 1u, TEST_LOCATION );
-
-  END_TEST;
-}
-
 int UtcDaliAccessibilityManagerActionReadIndicatorInformationSignalN(void)
 {
   ToolkitTestApplication application;
index d57d6b7..bda987d 100644 (file)
@@ -543,6 +543,10 @@ int UtcDaliAnimatedVectorImageVisualPlayRange(void)
   Renderer renderer = actor.GetRendererAt( 0u );
   DALI_TEST_CHECK( renderer );
 
+  Property::Map map = actor.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
+  Property::Value* value = map.Find( DevelImageVisual::Property::PLAY_RANGE );
+  DALI_TEST_EQUALS( value->Get< Vector2 >(), playRange, TEST_LOCATION );
+
   END_TEST;
 }
 
@@ -587,3 +591,114 @@ int UtcDaliAnimatedVectorImageVisualAnimationFinishedSignal(void)
 
   END_TEST;
 }
+
+int UtcDaliAnimatedVectorImageVisualJumpToCurrentProgress(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliAnimatedVectorImageVisualJumpToCurrentProgress" );
+
+  Property::Map propertyMap;
+  propertyMap.Add( Toolkit::Visual::Property::TYPE, DevelVisual::ANIMATED_VECTOR_IMAGE )
+             .Add( ImageVisual::Property::URL, TEST_VECTOR_IMAGE_FILE_NAME  );
+
+  Visual::Base visual = VisualFactory::Get().CreateVisual( propertyMap );
+  DALI_TEST_CHECK( visual );
+
+  DummyControl actor = DummyControl::New( true );
+  DummyControlImpl& dummyImpl = static_cast< DummyControlImpl& >( actor.GetImplementation() );
+  dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
+
+  Vector2 controlSize( 20.f, 30.f );
+  actor.SetSize( controlSize );
+
+  Stage::GetCurrent().Add( actor );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::JUMP_TO, 0.6f );
+
+  application.SendNotification();
+  application.Render();
+
+  Property::Map map = actor.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
+  Property::Value* value = map.Find( DevelImageVisual::Property::CURRENT_PROGRESS );
+  DALI_TEST_EQUALS( value->Get< float >(), 0.6f, TEST_LOCATION );
+
+  Vector2 playRange( 0.0f, 0.4f );
+
+  Property::Map attributes;
+  attributes.Add( DevelImageVisual::Property::PLAY_RANGE, playRange );
+  DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::UPDATE_PROPERTY, attributes );
+
+  DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::JUMP_TO, 0.8f );
+
+  application.SendNotification();
+  application.Render();
+
+  map = actor.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
+  value = map.Find( DevelImageVisual::Property::CURRENT_PROGRESS );
+  DALI_TEST_EQUALS( value->Get< float >(), 0.4f, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliAnimatedVectorImageVisualUpdateProperty(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliAnimatedVectorImageVisualJumpToCurrentProgress" );
+
+  Vector2 playRange( 0.2f, 0.8f );
+
+  Property::Map propertyMap;
+  propertyMap.Add( Toolkit::Visual::Property::TYPE, DevelVisual::ANIMATED_VECTOR_IMAGE )
+             .Add( ImageVisual::Property::URL, TEST_VECTOR_IMAGE_FILE_NAME  )
+             .Add( DevelImageVisual::Property::LOOP_COUNT, 3  )
+             .Add( DevelImageVisual::Property::PLAY_RANGE, playRange  );
+
+  Visual::Base visual = VisualFactory::Get().CreateVisual( propertyMap );
+  DALI_TEST_CHECK( visual );
+
+  DummyControl actor = DummyControl::New( true );
+  DummyControlImpl& dummyImpl = static_cast< DummyControlImpl& >( actor.GetImplementation() );
+  dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
+
+  Vector2 controlSize( 20.f, 30.f );
+  actor.SetSize( controlSize );
+
+  Stage::GetCurrent().Add( actor );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  Property::Map map = actor.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
+  Property::Value* value = map.Find( DevelImageVisual::Property::LOOP_COUNT );
+  DALI_TEST_EQUALS( value->Get< int >(), 3, TEST_LOCATION );
+
+  value = map.Find( DevelImageVisual::Property::PLAY_RANGE );
+  DALI_TEST_EQUALS( value->Get< Vector2 >(), playRange, TEST_LOCATION );
+
+  Vector2 newPlayRange( 0.4f, 1.0f );
+
+  Property::Map attributes;
+  attributes.Add( DevelImageVisual::Property::PLAY_RANGE, newPlayRange );
+  attributes.Add( DevelImageVisual::Property::LOOP_COUNT, 5 );
+
+  DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::UPDATE_PROPERTY, attributes );
+
+  application.SendNotification();
+  application.Render();
+
+  map = actor.GetProperty< Property::Map >( DummyControl::Property::TEST_VISUAL );
+  value = map.Find( DevelImageVisual::Property::LOOP_COUNT );
+  DALI_TEST_EQUALS( value->Get< int >(), 5, TEST_LOCATION );
+
+  value = map.Find( DevelImageVisual::Property::PLAY_RANGE );
+  DALI_TEST_EQUALS( value->Get< Vector2 >(), newPlayRange, TEST_LOCATION );
+
+  END_TEST;
+}
index 77439d4..4d8bfe0 100644 (file)
@@ -28,6 +28,7 @@
 #include <dali-toolkit/dali-toolkit.h>
 #include <test-button.h>
 #include <test-animation-data.h>
+#include <dummy-control.h>
 
 
 #define STRINGIFY(A)#A
@@ -1791,6 +1792,43 @@ int UtcDaliBuilderBuilderControl(void)
   END_TEST;
 }
 
+int UtcDaliBuilderCustomControl(void)
+{
+  ToolkitTestApplication application;
+
+  std::string json(
+    "{"
+       "\"stage\":"
+       "[{"
+         "\"type\": \"DummyControl\","
+         "\"name\": \"I can haz custom Control\""
+      "}]"
+    "}"
+  );
+
+  Actor rootActor = Actor::New();
+  Stage::GetCurrent().Add( rootActor );
+
+  Builder builder = Builder::New();
+  builder.LoadFromString( json );
+  builder.AddActors( rootActor );
+
+  application.SendNotification();
+  application.Render();
+
+  Actor customControl = rootActor.FindChildByName( "I can haz custom Control" );
+
+  // Test that we have the correct type of custom control
+  DummyControl dummyControl = DummyControl::DownCast( customControl );
+  DALI_TEST_CHECK( dummyControl );
+  if( dummyControl )
+  {
+    DALI_TEST_CHECK( typeid(dummyControl.GetImplementation()) == typeid(DummyControlImpl) );
+  }
+
+  END_TEST;
+}
+
 int UtcDaliBuilderActionsWithParams(void)
 {
   ToolkitTestApplication application;
index 8e1673e..0921d61 100644 (file)
@@ -51,6 +51,15 @@ void utc_dali_toolkit_control_wrapper_cleanup(void)
 namespace
 {
 bool gOnRelayout = false;
+
+static bool gKeyInputFocusCallBackCalled;
+
+static void TestKeyInputFocusCallback( Control control )
+{
+  tet_infoline(" TestKeyInputFocusCallback");
+
+  gKeyInputFocusCallBackCalled = true;
+}
 } // namespace
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -810,3 +819,23 @@ int UtcDaliControlWrapperAnimateVisual(void)
 
   END_TEST;
 }
+
+int UtcDaliControlWrapperEmitKeyFocusSignal(void)
+{
+  ToolkitTestApplication application;
+
+  Impl::TestCustomControl* controlWrapperImpl = new ::Impl::TestCustomControl( Toolkit::Internal::ControlWrapper::CONTROL_BEHAVIOUR_DEFAULT );
+  ControlWrapper controlWrapper = ControlWrapper::New( customControlTypeName, *controlWrapperImpl );
+
+  gKeyInputFocusCallBackCalled = false;
+  controlWrapper.KeyInputFocusGainedSignal().Connect(&TestKeyInputFocusCallback);
+
+  application.SendNotification();
+  application.Render();
+
+  controlWrapperImpl->EmitKeyInputFocusSignal( true );
+
+  DALI_TEST_CHECK( gKeyInputFocusCallBackCalled );
+
+  END_TEST;
+}
\ No newline at end of file
index 224c6f4..9438589 100644 (file)
@@ -44,6 +44,44 @@ void utc_dali_toolkit_grid_layouting_cleanup(void)
   test_return_value = TET_PASS;
 }
 
+int UtcDaliLayouting_GridLayout00(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliLayouting_GridLayout00 1 Column, 0 Items");
+
+  const auto NUMBER_OF_COLUMNS = 1;
+  const auto NUMBER_OF_ITEMS = 0;
+
+  tet_printf( "Testing %d columns with %d items\n", NUMBER_OF_COLUMNS, NUMBER_OF_ITEMS );
+
+  Stage stage = Stage::GetCurrent();
+
+  auto rootControl = Control::New();
+  auto absoluteLayout = AbsoluteLayout::New();
+  DevelControl::SetLayout( rootControl, absoluteLayout );
+  rootControl.SetName( "AbsoluteLayout" );
+  stage.Add( rootControl );
+
+  auto gridContainer = Control::New();
+  auto gridLayout = Grid::New();
+  gridLayout.SetNumberOfColumns( NUMBER_OF_COLUMNS );
+  gridContainer.SetName( "GridLayout");
+  DevelControl::SetLayout( gridContainer, gridLayout );
+  gridContainer.SetProperty( LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+  gridContainer.SetProperty( LayoutItem::ChildProperty::HEIGHT_SPECIFICATION,  ChildLayoutData::WRAP_CONTENT );
+
+  rootControl.Add( gridContainer );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  tet_printf( "Confirm number of columns is as set\n");
+  DALI_TEST_EQUALS( gridLayout.GetNumberOfColumns(), NUMBER_OF_COLUMNS, TEST_LOCATION );
+
+  END_TEST;
+}
+
 int UtcDaliLayouting_GridLayout01(void)
 {
   ToolkitTestApplication application;
@@ -627,4 +665,4 @@ int UtcDaliLayouting_GridLayoutDownCast(void)
   DALI_TEST_CHECK( gridLayoutCandidate );
 
   END_TEST;
-}
\ No newline at end of file
+}
index 29370b7..20686c6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@
 #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 <dali-toolkit/devel-api/visuals/image-visual-actions-devel.h>
 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
 
 #include <test-native-image.h>
@@ -353,7 +354,7 @@ int UtcDaliImageViewSetGetProperty03(void)
   Property::Value value = renderer.GetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA );
   bool enable;
   DALI_TEST_CHECK( value.Get( enable ) );
-  DALI_TEST_CHECK( !enable );
+  DALI_TEST_CHECK( enable );
 
   // pre-multiplied alpha blending
   imageView.SetProperty( Toolkit::ImageView::Property::PRE_MULTIPLIED_ALPHA, true );
@@ -376,6 +377,205 @@ int UtcDaliImageViewSetGetProperty03(void)
   END_TEST;
 }
 
+int UtcDaliImageViewPreMultipliedAlphaPng(void)
+{
+  ToolkitTestApplication application;
+
+  // Set up trace debug
+  TestGlAbstraction& gl = application.GetGlAbstraction();
+  TraceCallStack& textureTrace = gl.GetTextureTrace();
+  textureTrace.Enable( true );
+
+  Property::Map imageMap;
+  imageMap[ ImageVisual::Property::URL ] = gImage_34_RGBA;
+  imageMap[ ImageVisual::Property::RELEASE_POLICY] = ImageVisual::ReleasePolicy::NEVER;   // To keep the texture cache
+
+  ImageView imageView1 = ImageView::New();
+  imageView1.SetProperty( ImageView::Property::IMAGE, imageMap );
+
+  Stage::GetCurrent().Add( imageView1 );
+
+  Property::Value value = imageView1.GetProperty( ImageView::Property::PRE_MULTIPLIED_ALPHA );
+  bool enable;
+  DALI_TEST_CHECK( value.Get( enable ) );
+  DALI_TEST_CHECK( enable );    // Default value is true
+
+  // loading started, this waits for the loader thread for max 30 seconds
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  value = imageView1.GetProperty( ImageView::Property::PRE_MULTIPLIED_ALPHA );
+  DALI_TEST_CHECK( value.Get( enable ) );
+  DALI_TEST_CHECK( enable );    // Keep true
+
+  // conventional alpha blending
+  Renderer renderer1 = imageView1.GetRendererAt( 0 );
+  value = renderer1.GetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA );
+  DALI_TEST_CHECK( value.Get( enable ) );
+  DALI_TEST_CHECK( enable );
+
+  int srcFactorRgb    = renderer1.GetProperty<int>( Renderer::Property::BLEND_FACTOR_SRC_RGB );
+  int destFactorRgb   = renderer1.GetProperty<int>( Renderer::Property::BLEND_FACTOR_DEST_RGB );
+  int srcFactorAlpha  = renderer1.GetProperty<int>( Renderer::Property::BLEND_FACTOR_SRC_ALPHA );
+  int destFactorAlpha = renderer1.GetProperty<int>( Renderer::Property::BLEND_FACTOR_DEST_ALPHA );
+  DALI_TEST_CHECK( srcFactorRgb == BlendFactor::ONE );
+  DALI_TEST_CHECK( destFactorRgb == BlendFactor::ONE_MINUS_SRC_ALPHA );
+  DALI_TEST_CHECK( srcFactorAlpha == BlendFactor::ONE );
+  DALI_TEST_CHECK( destFactorAlpha == BlendFactor::ONE_MINUS_SRC_ALPHA );
+
+  DALI_TEST_EQUALS( textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION );  // A new texture should be generated.
+  textureTrace.Reset();
+
+  // Disable pre-multiplied alpha blending
+  imageView1.SetProperty( ImageView::Property::PRE_MULTIPLIED_ALPHA, false );
+
+  // Reload the image
+  Property::Map attributes;
+  DevelControl::DoAction( imageView1, ImageView::Property::IMAGE, DevelImageVisual::Action::RELOAD, attributes );
+
+  // loading started, this waits for the loader thread for max 30 seconds
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  value = imageView1.GetProperty( ImageView::Property::PRE_MULTIPLIED_ALPHA );
+  DALI_TEST_CHECK( value.Get( enable ) );
+  DALI_TEST_CHECK( !enable );
+
+  // conventional alpha blending
+  value = renderer1.GetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA );
+  DALI_TEST_CHECK( value.Get( enable ) );
+  DALI_TEST_CHECK( !enable );
+
+  srcFactorRgb    = renderer1.GetProperty<int>( Renderer::Property::BLEND_FACTOR_SRC_RGB );
+  destFactorRgb   = renderer1.GetProperty<int>( Renderer::Property::BLEND_FACTOR_DEST_RGB );
+  srcFactorAlpha  = renderer1.GetProperty<int>( Renderer::Property::BLEND_FACTOR_SRC_ALPHA );
+  destFactorAlpha = renderer1.GetProperty<int>( Renderer::Property::BLEND_FACTOR_DEST_ALPHA );
+  DALI_TEST_CHECK( srcFactorRgb == BlendFactor::SRC_ALPHA );
+  DALI_TEST_CHECK( destFactorRgb == BlendFactor::ONE_MINUS_SRC_ALPHA );
+  DALI_TEST_CHECK( srcFactorAlpha == BlendFactor::ONE );
+  DALI_TEST_CHECK( destFactorAlpha == BlendFactor::ONE_MINUS_SRC_ALPHA );
+
+  DALI_TEST_EQUALS( textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION );  // A new texture should be generated.
+  textureTrace.Reset();
+
+  // Make a new ImageView using the same image
+  ImageView imageView2 = ImageView::New();
+  imageView2.SetProperty( ImageView::Property::IMAGE, imageMap );
+
+  Stage::GetCurrent().Add( imageView2 );
+
+  application.SendNotification();
+  application.Render();
+
+  Renderer renderer2 = imageView2.GetRendererAt( 0 );
+  value = renderer2.GetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA );
+  DALI_TEST_CHECK( value.Get( enable ) );
+  DALI_TEST_CHECK( enable );
+
+  srcFactorRgb    = renderer2.GetProperty<int>( Renderer::Property::BLEND_FACTOR_SRC_RGB );
+  destFactorRgb   = renderer2.GetProperty<int>( Renderer::Property::BLEND_FACTOR_DEST_RGB );
+  srcFactorAlpha  = renderer2.GetProperty<int>( Renderer::Property::BLEND_FACTOR_SRC_ALPHA );
+  destFactorAlpha = renderer2.GetProperty<int>( Renderer::Property::BLEND_FACTOR_DEST_ALPHA );
+  DALI_TEST_CHECK( srcFactorRgb == BlendFactor::ONE );
+  DALI_TEST_CHECK( destFactorRgb == BlendFactor::ONE_MINUS_SRC_ALPHA );
+  DALI_TEST_CHECK( srcFactorAlpha == BlendFactor::ONE );
+  DALI_TEST_CHECK( destFactorAlpha == BlendFactor::ONE_MINUS_SRC_ALPHA );
+
+  DALI_TEST_EQUALS( textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION ); // The cached texture should be used.
+
+  END_TEST;
+}
+
+int UtcDaliImageViewPreMultipliedAlphaJpg(void)
+{
+  ToolkitTestApplication application;
+
+  // Set up trace debug
+  TestGlAbstraction& gl = application.GetGlAbstraction();
+  TraceCallStack& textureTrace = gl.GetTextureTrace();
+  textureTrace.Enable( true );
+
+  Property::Map imageMap;
+  imageMap[ ImageVisual::Property::URL ] = gImage_600_RGB;
+  imageMap[ ImageVisual::Property::RELEASE_POLICY] = ImageVisual::ReleasePolicy::NEVER;   // To keep the texture cache
+
+  ImageView imageView1 = ImageView::New();
+  imageView1.SetProperty( ImageView::Property::IMAGE, imageMap );
+
+  Stage::GetCurrent().Add( imageView1 );
+
+  Property::Value value = imageView1.GetProperty( ImageView::Property::PRE_MULTIPLIED_ALPHA );
+  bool enable;
+  DALI_TEST_CHECK( value.Get( enable ) );
+  DALI_TEST_CHECK( enable );    // Default value is true
+
+  // loading started, this waits for the loader thread for max 30 seconds
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  value = imageView1.GetProperty( ImageView::Property::PRE_MULTIPLIED_ALPHA );
+  DALI_TEST_CHECK( value.Get( enable ) );
+  DALI_TEST_CHECK( !enable );    // Should be false after loading
+
+  // conventional alpha blending
+  Renderer renderer1 = imageView1.GetRendererAt( 0 );
+  value = renderer1.GetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA );
+  DALI_TEST_CHECK( value.Get( enable ) );
+  DALI_TEST_CHECK( !enable );
+
+  int srcFactorRgb    = renderer1.GetProperty<int>( Renderer::Property::BLEND_FACTOR_SRC_RGB );
+  int destFactorRgb   = renderer1.GetProperty<int>( Renderer::Property::BLEND_FACTOR_DEST_RGB );
+  int srcFactorAlpha  = renderer1.GetProperty<int>( Renderer::Property::BLEND_FACTOR_SRC_ALPHA );
+  int destFactorAlpha = renderer1.GetProperty<int>( Renderer::Property::BLEND_FACTOR_DEST_ALPHA );
+  DALI_TEST_CHECK( srcFactorRgb == BlendFactor::SRC_ALPHA );
+  DALI_TEST_CHECK( destFactorRgb == BlendFactor::ONE_MINUS_SRC_ALPHA );
+  DALI_TEST_CHECK( srcFactorAlpha == BlendFactor::ONE );
+  DALI_TEST_CHECK( destFactorAlpha == BlendFactor::ONE_MINUS_SRC_ALPHA );
+
+  DALI_TEST_EQUALS( textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION );  // A new texture should be generated.
+  textureTrace.Reset();
+
+  ImageView imageView2 = ImageView::New();
+  imageView2.SetProperty( ImageView::Property::IMAGE, imageMap );
+
+  // Disable pre-multiplied alpha blending
+  imageView2.SetProperty( ImageView::Property::PRE_MULTIPLIED_ALPHA, false );
+
+  Stage::GetCurrent().Add( imageView2 );
+
+  application.SendNotification();
+  application.Render();
+
+  value = imageView2.GetProperty( ImageView::Property::PRE_MULTIPLIED_ALPHA );
+  DALI_TEST_CHECK( value.Get( enable ) );
+  DALI_TEST_CHECK( !enable );
+
+  // conventional alpha blending
+  Renderer renderer2 = imageView2.GetRendererAt( 0 );
+  value = renderer2.GetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA );
+  DALI_TEST_CHECK( value.Get( enable ) );
+  DALI_TEST_CHECK( !enable );
+
+  srcFactorRgb    = renderer2.GetProperty<int>( Renderer::Property::BLEND_FACTOR_SRC_RGB );
+  destFactorRgb   = renderer2.GetProperty<int>( Renderer::Property::BLEND_FACTOR_DEST_RGB );
+  srcFactorAlpha  = renderer2.GetProperty<int>( Renderer::Property::BLEND_FACTOR_SRC_ALPHA );
+  destFactorAlpha = renderer2.GetProperty<int>( Renderer::Property::BLEND_FACTOR_DEST_ALPHA );
+  DALI_TEST_CHECK( srcFactorRgb == BlendFactor::SRC_ALPHA );
+  DALI_TEST_CHECK( destFactorRgb == BlendFactor::ONE_MINUS_SRC_ALPHA );
+  DALI_TEST_CHECK( srcFactorAlpha == BlendFactor::ONE );
+  DALI_TEST_CHECK( destFactorAlpha == BlendFactor::ONE_MINUS_SRC_ALPHA );
+
+  DALI_TEST_EQUALS( textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION ); // The cached texture should be used.
+
+  END_TEST;
+}
+
 int UtcDaliImageViewPixelArea(void)
 {
   // Test pixel area property
@@ -1841,6 +2041,8 @@ int UtcDaliImageViewCustomShader(void)
     application.SendNotification();
     application.Render();
 
+    DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
     Renderer renderer = imageView.GetRendererAt( 0 );
     Shader shader2 = renderer.GetShader();
     Property::Value value = shader2.GetProperty( Shader::Property::PROGRAM );
@@ -1873,6 +2075,7 @@ int UtcDaliImageViewCustomShader(void)
 
     application.SendNotification();
     application.Render();
+    DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
 
     Renderer renderer = imageView.GetRendererAt( 0 );
     Shader shader2 = renderer.GetShader();
@@ -1910,6 +2113,7 @@ int UtcDaliImageViewCustomShader(void)
 
     application.SendNotification();
     application.Render();
+    DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
 
     Renderer renderer = imageView.GetRendererAt( 0 );
     Shader shader2 = renderer.GetShader();
@@ -1947,6 +2151,7 @@ int UtcDaliImageViewCustomShader(void)
 
     application.SendNotification();
     application.Render();
+    DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
 
     Renderer renderer = imageView.GetRendererAt( 0 );
     Shader shader2 = renderer.GetShader();
@@ -1963,3 +2168,60 @@ int UtcDaliImageViewCustomShader(void)
 
   END_TEST;
 }
+
+
+namespace
+{
+static int gFailCounter = 0;
+const int MAX_RETRIES(3);
+
+void ReloadImage(ImageView imageView)
+{
+  Property::Map imageImmediateLoadingMap;
+  imageImmediateLoadingMap[ ImageVisual::Property::URL ] = "Non-existant-image.jpg";
+  imageImmediateLoadingMap[ ImageVisual::Property::LOAD_POLICY ] =  ImageVisual::LoadPolicy::IMMEDIATE;
+
+  tet_infoline("Immediate load an image");
+  imageView.SetProperty( ImageView::Property::IMAGE, imageImmediateLoadingMap );
+}
+
+void ResourceFailedReload( Control control )
+{
+  gFailCounter++;
+  if( gFailCounter < MAX_RETRIES )
+  {
+    ReloadImage(ImageView::DownCast(control));
+  }
+}
+}
+
+int UtcDaliImageViewReloadFailedOnResourceReadySignal(void)
+{
+  tet_infoline("Test reloading failed image from within signal handler.");
+
+  ToolkitTestApplication application;
+
+  gFailCounter = 0;
+
+  ImageView imageView = ImageView::New();
+  imageView.ResourceReadySignal().Connect( &ResourceFailedReload );
+  DALI_TEST_EQUALS( gFailCounter, 0, TEST_LOCATION );
+  ReloadImage(imageView);
+
+  // loading started, this waits for the loader thread to complete
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+  application.SendNotification();
+
+  DALI_TEST_EQUALS( gFailCounter, 1, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+  application.SendNotification();
+
+  DALI_TEST_EQUALS( gFailCounter, 2, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+  application.SendNotification();
+  DALI_TEST_EQUALS( gFailCounter, 3, TEST_LOCATION );
+
+  END_TEST;
+}
index 90dd9e7..a15ecf6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
 
 #include <iostream>
 #include <stdlib.h>
+#include <vector>
 #include <dali-toolkit-test-suite-utils.h>
 #include <toolkit-timer.h>
 #include <toolkit-event-thread-callback.h>
@@ -43,6 +44,7 @@ void dali_image_visual_cleanup(void)
 namespace
 {
 const char* TEST_IMAGE_FILE_NAME =  TEST_RESOURCE_DIR  "/gallery-small-1.jpg";
+const char* TEST_BROKEN_IMAGE_FILE_NAME =  TEST_RESOURCE_DIR  "/a-random-nonimage.jpg";
 const char* TEST_LARGE_IMAGE_FILE_NAME =  TEST_RESOURCE_DIR "/tbcol.png";
 const char* TEST_SMALL_IMAGE_FILE_NAME = TEST_RESOURCE_DIR "/icon-edit.png";
 const char* TEST_REMOTE_IMAGE_FILE_NAME = "https://www.tizen.org/sites/all/themes/tizen_theme/logo.png";
@@ -53,10 +55,15 @@ const char* TEST_ROTATED_IMAGE =  TEST_RESOURCE_DIR  "/keyboard-Landscape.jpg";
 
 
 bool gResourceReadySignalFired = false;
-
+std::vector<int> gReadyIds = {};
 void ResourceReadySignal( Control control )
 {
   gResourceReadySignalFired = true;
+  gReadyIds.push_back(control.GetId());
+}
+void ClearReadyIds()
+{
+  gReadyIds.clear();
 }
 
 Actor CreateActorWithImageVisual(const Property::Map& map)
@@ -2178,3 +2185,97 @@ int UtcDaliImageVisualCustomShader(void)
 
   END_TEST;
 }
+
+
+void ResourceReadyLoadNext( Control control )
+{
+  static int callNumber = 0;
+
+  gResourceReadySignalFired = true;
+  gReadyIds.push_back(control.GetId());
+
+  if( callNumber == 0 )
+  {
+    DALI_TEST_EQUALS( control.GetVisualResourceStatus(DummyControl::Property::TEST_VISUAL), Toolkit::Visual::ResourceStatus::FAILED, TEST_LOCATION );
+
+    tet_infoline( "Create visual with loaded image from within the signal handler" );
+    VisualFactory factory = VisualFactory::Get();
+    Visual::Base imageVisual = factory.CreateVisual( TEST_IMAGE_FILE_NAME, ImageDimensions{20,30} );
+
+    Impl::DummyControl& controlImpl = static_cast<Impl::DummyControl&>(control.GetImplementation());
+    controlImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, imageVisual ); // This should trigger another signal.
+    callNumber = 1;
+  }
+  else
+  {
+    tet_infoline( "3rd signal called" );
+    DALI_TEST_CHECK(true);
+  }
+}
+
+int UtcDaliImageVisualLoadReady01(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliImageVisualLoadReady01");
+  tet_infoline( "First part:  Load an image visual for one resource, then another image visual for a second resource.");
+  tet_infoline( "Second part, In the ready signal for the second image visual, add a 3rd visual with the first URL" );
+  tet_infoline( "Should get a ready signal for all three visuals");
+
+  ClearReadyIds();
+
+  tet_infoline( "Create a control and connect to resource ready signal" );
+  DummyControl actor = DummyControl::New(true);
+  int actor1Id = actor.GetId();
+  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( "Create visual with IMMEDIATE load policy" );
+  Visual::Base imageVisual1 = CreateVisualWithPolicy( TEST_IMAGE_FILE_NAME, ImageVisual::Property::LOAD_POLICY, ImageVisual::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, imageVisual1 );
+
+
+  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( gResourceReadySignalFired, true, TEST_LOCATION );
+  DALI_TEST_EQUALS( gReadyIds[0], actor1Id, TEST_LOCATION );
+
+
+  tet_infoline( "Original control correctly signalled, now testing failing image" );
+
+  gResourceReadySignalFired = false; // Reset signal check ready for testing next Control
+  ClearReadyIds();
+
+  Visual::Base imageVisual2 = CreateVisualWithPolicy( TEST_BROKEN_IMAGE_FILE_NAME, ImageVisual::Property::LOAD_POLICY, ImageVisual::LoadPolicy::IMMEDIATE );
+
+  DummyControl actor2 = DummyControl::New(true);
+  int actor2Id = actor2.GetId();
+  Impl::DummyControl& dummyImpl2 = static_cast<Impl::DummyControl&>(actor2.GetImplementation());
+  actor2.ResourceReadySignal().Connect( &ResourceReadyLoadNext);
+
+  tet_infoline( "Registering visual this should trigger the ready signal when the image fails to load" );
+  dummyImpl2.RegisterVisual( DummyControl::Property::TEST_VISUAL, imageVisual2 );
+
+  actor2.SetSize(200.f, 200.f);
+  Stage::GetCurrent().Add(actor2);
+
+  tet_infoline( "Wait for loading thread to finish");
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+  DALI_TEST_EQUALS( gResourceReadySignalFired, true, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( gReadyIds[0], actor2Id, TEST_LOCATION);
+
+  tet_infoline( "Check for 3rd signal");
+  application.SendNotification();
+  DALI_TEST_EQUALS( gReadyIds.size(), 2, TEST_LOCATION );
+  DALI_TEST_EQUALS( gReadyIds[1], actor2Id, TEST_LOCATION);
+
+  END_TEST;
+}
index a527eac..438a496 100644 (file)
@@ -217,6 +217,7 @@ void CleanupTest()
 
 int UtcDaliScrollViewPagePathEffectSetup(void)
 {
+  ToolkitTestApplication application;
   tet_infoline(" UtcDaliScrollViewPagePathEffectSetup");
 
   ScrollViewPagePathEffect effect;
index 3e3b0e3..251b339 100755 (executable)
@@ -761,9 +761,9 @@ int UtcDaliTextEditorSetPropertyP(void)
   Property::Map underlineMapSet;
   Property::Map underlineMapGet;
 
-  underlineMapSet.Insert( "enable", "true" );
-  underlineMapSet.Insert( "color", "red" );
-  underlineMapSet.Insert( "height", "1" );
+  underlineMapSet.Insert( "enable", true );
+  underlineMapSet.Insert( "color", Color::RED );
+  underlineMapSet.Insert( "height", 1 );
 
   editor.SetProperty( TextEditor::Property::UNDERLINE, underlineMapSet );
 
@@ -2596,9 +2596,9 @@ int utcDaliTextEditorUnderPropertyStringP(void)
   // Check the input underline property
   Property::Map underlineMapSet;
   Property::Map underlineMapGet;
-  underlineMapSet.Insert( "enable", "true" );
-  underlineMapSet.Insert( "color", "blue" );
-  underlineMapSet.Insert( "height", "2" );
+  underlineMapSet.Insert( "enable", true );
+  underlineMapSet.Insert( "color", Color::BLUE );
+  underlineMapSet.Insert( "height", 2 );
 
   editor.SetProperty( TextEditor::Property::UNDERLINE, underlineMapSet );
   underlineMapGet = editor.GetProperty<Property::Map>( TextEditor::Property::UNDERLINE );
index 39cd605..8b1005f 100755 (executable)
@@ -806,9 +806,9 @@ int UtcDaliTextFieldSetPropertyP(void)
   Property::Map underlineMapSet;
   Property::Map underlineMapGet;
 
-  underlineMapSet.Insert( "enable", "true" );
-  underlineMapSet.Insert( "color", "red" );
-  underlineMapSet.Insert( "height", "1" );
+  underlineMapSet.Insert( "enable", true );
+  underlineMapSet.Insert( "color", Color::RED );
+  underlineMapSet.Insert( "height", 1 );
 
   // Check the underline property
   field.SetProperty( TextField::Property::UNDERLINE, underlineMapSet );
index 551acf2..1208543 100755 (executable)
@@ -372,9 +372,9 @@ int UtcDaliToolkitTextLabelSetPropertyP(void)
   Property::Map underlineMapSet;
   Property::Map underlineMapGet;
 
-  underlineMapSet.Insert( "enable", "false" );
-  underlineMapSet.Insert( "color", "blue" );
-  underlineMapSet.Insert( "height", "0" );
+  underlineMapSet.Insert( "enable", false );
+  underlineMapSet.Insert( "color", Color::BLUE );
+  underlineMapSet.Insert( "height", 0 );
 
   underlineMapGet = label.GetProperty<Property::Map>( TextLabel::Property::UNDERLINE );
   DALI_TEST_EQUALS( underlineMapGet.Count(), underlineMapSet.Count(), TEST_LOCATION );
@@ -465,9 +465,9 @@ int UtcDaliToolkitTextLabelSetPropertyP(void)
 
   // Check the underline property
   underlineMapSet.Clear();
-  underlineMapSet.Insert( "enable", "true" );
-  underlineMapSet.Insert( "color", "red" );
-  underlineMapSet.Insert( "height", "1" );
+  underlineMapSet.Insert( "enable", true );
+  underlineMapSet.Insert( "color", Color::RED );
+  underlineMapSet.Insert( "height", 1 );
 
   label.SetProperty( TextLabel::Property::UNDERLINE, underlineMapSet );
 
@@ -479,9 +479,9 @@ int UtcDaliToolkitTextLabelSetPropertyP(void)
   DALI_TEST_EQUALS( DaliTestCheckMaps( underlineMapGet, underlineMapSet ), true, TEST_LOCATION );
 
   underlineMapSet.Clear();
-  underlineMapSet.Insert( Toolkit::DevelText::Underline::Property::ENABLE, "true" );
-  underlineMapSet.Insert( Toolkit::DevelText::Underline::Property::COLOR, "green" );
-  underlineMapSet.Insert( Toolkit::DevelText::Underline::Property::HEIGHT, "2" );
+  underlineMapSet.Insert( Toolkit::DevelText::Underline::Property::ENABLE, true );
+  underlineMapSet.Insert( Toolkit::DevelText::Underline::Property::COLOR, Color::GREEN );
+  underlineMapSet.Insert( Toolkit::DevelText::Underline::Property::HEIGHT, 2 );
 
   label.SetProperty( TextLabel::Property::UNDERLINE, underlineMapSet );
 
@@ -496,9 +496,9 @@ int UtcDaliToolkitTextLabelSetPropertyP(void)
   underlineMapSet.Clear();
 
   Property::Map underlineDisabledMapGet;
-  underlineDisabledMapGet.Insert( "enable", "false" );
-  underlineDisabledMapGet.Insert( "color", "green" );
-  underlineDisabledMapGet.Insert( "height", "2" );
+  underlineDisabledMapGet.Insert( "enable", false );
+  underlineDisabledMapGet.Insert( "color", Color::GREEN );
+  underlineDisabledMapGet.Insert( "height", 2 );
 
   label.SetProperty( TextLabel::Property::UNDERLINE, underlineMapSet );
 
@@ -646,8 +646,8 @@ int UtcDaliToolkitTextlabelAtlasRenderP(void)
   label.SetProperty( TextLabel::Property::MULTI_LINE, true );
 
   Property::Map underlineMap;
-  underlineMap.Insert( "enable", "true" );
-  underlineMap.Insert( "color", "red" );
+  underlineMap.Insert( "enable", true );
+  underlineMap.Insert( "color", Color::RED );
   label.SetProperty( TextLabel::Property::UNDERLINE, underlineMap );
 
   Property::Map shadowMap;
index 89a95ba..72370db 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -26,7 +26,6 @@ using namespace Dali::Toolkit;
 
 namespace
 {
-
 } // namespace
 
 
@@ -152,6 +151,3 @@ int UtcDaliTextureManagerRemoveN(void)
 
   END_TEST;
 }
-
-
-
index c4df701..aee2e2f 100644 (file)
@@ -1193,7 +1193,7 @@ int UtcDaliVisualGetPropertyMap10(void)
   propertyMap.Insert( "shadow", shadowMapSet.Add("color", Color::RED).Add("offset", Vector2(2.0f, 2.0f)).Add("blurRadius", 3.0f) );
 
   Property::Map underlineMapSet;
-  propertyMap.Insert( "underline", underlineMapSet.Add("enable", "true").Add("color", "green").Add("height", "1") );
+  propertyMap.Insert( "underline", underlineMapSet.Add("enable", true).Add("color", Color::GREEN).Add("height", 1) );
 
   Property::Map outlineMapSet;
   propertyMap.Insert( "outline", outlineMapSet.Add("color", Color::YELLOW).Add("width", 1) );
@@ -3294,7 +3294,7 @@ int UtcDaliVisualPremultipliedAlpha(void)
 
   VisualFactory factory = VisualFactory::Get();
 
-  // image visual, test default value ( false )
+  // image visual, test default value ( true )
   {
     Visual::Base imageVisual = factory.CreateVisual(
           Property::Map()
@@ -3307,7 +3307,7 @@ int UtcDaliVisualPremultipliedAlpha(void)
 
     // test values
     DALI_TEST_CHECK( value );
-    DALI_TEST_EQUALS( value->Get<bool>(), false, TEST_LOCATION );
+    DALI_TEST_EQUALS( value->Get<bool>(), true, TEST_LOCATION );
   }
 
   // image visual, override premultiplied
@@ -3316,7 +3316,7 @@ int UtcDaliVisualPremultipliedAlpha(void)
           Property::Map()
           .Add( Toolkit::Visual::Property::TYPE, Visual::IMAGE )
           .Add( ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME )
-          .Add( Visual::Property::PREMULTIPLIED_ALPHA, true ) );
+          .Add( Visual::Property::PREMULTIPLIED_ALPHA, false ) );
 
     Dali::Property::Map visualMap;
     imageVisual.CreatePropertyMap( visualMap );
@@ -3324,7 +3324,7 @@ int UtcDaliVisualPremultipliedAlpha(void)
 
     // test values
     DALI_TEST_CHECK( value );
-    DALI_TEST_EQUALS( value->Get<bool>(), true, TEST_LOCATION);
+    DALI_TEST_EQUALS( value->Get<bool>(), false, TEST_LOCATION);
   }
 
   // svg visual ( premultiplied alpha by default is true )
index 4fcf095..c895b4f 100755 (executable)
@@ -362,12 +362,17 @@ ALIASES += SINCE_1_3_5="@since 1.3.5"
 ALIASES += SINCE_1_3_9="@since 1.3.9"
 ALIASES += SINCE_1_3_15="@since 1.3.15"
 
+#Extra tags for Tizen 5.5
+ALIASES += SINCE_1_3_31="@since 1.3.31"
+
 ALIASES += DEPRECATED_1_0="@deprecated Deprecated since 1.0"
 ALIASES += DEPRECATED_1_1="@deprecated Deprecated since 1.1"
 ALIASES += DEPRECATED_1_2_8="@deprecated Deprecated since 1.2.8"
 ALIASES += DEPRECATED_1_2_10="@deprecated Deprecated since 1.2.10"
 ALIASES += DEPRECATED_1_2="@deprecated Deprecated since 1.2"
 ALIASES += DEPRECATED_1_3="@deprecated Deprecated since 1.3"
+ALIASES += DEPRECATED_1_3_39="@deprecated Deprecated since 1.3.39"
+ALIASES += DEPRECATED_1_3_51="@deprecated Deprecated since 1.3.51"
 ALIASES += DEPRECATED_1_4="@deprecated Deprecated since 1.4"
 
 ALIASES += PLATFORM=""
@@ -386,7 +391,7 @@ ALIASES += REMARK_RAWVIDEO=""
 #ALIASES += SINCE_1_1="\par Since:\n 3.0, DALi version 1.1"
 #ALIASES += SINCE_1_2="\par Since:\n 4.0, DALi version 1.2"
 #ALIASES += SINCE_1_3="\par Since:\n 5.0, DALi version 1.3"
-#ALIASES += SINCE_1_4="\par Since:\n 6.0, DALi version 1.4"
+#ALIASES += SINCE_1_4="\par Since:\n 5.5, DALi version 1.4"
 
 ## Extra tags for Tizen 3.0
 #ALIASES += SINCE_1_2_2="\par Since:\n 3.0, DALi version 1.2.2"
@@ -402,6 +407,9 @@ ALIASES += REMARK_RAWVIDEO=""
 #ALIASES += SINCE_1_3_9="\par Since:\n 4.0, DALi version 1.3.9"
 #ALIASES += SINCE_1_3_15="\par Since:\n 4.0, DALi version 1.3.15"
 
+#Extra tags for Tizen 5.5
+#ALIASES += SINCE_1_3_31="\par Since:\n 5.5, DALi version 1.3.31"
+
 ## DALi has no deprecated API in Tizen 2.4 because it's DALi's first release.
 ## Thus deprecated APIs in DALi 1.0.xx will be deprecated in Tizen 3.0.
 #ALIASES += DEPRECATED_1_0="@deprecated Deprecated since 3.0, DALi version 1.0"
@@ -410,7 +418,9 @@ ALIASES += REMARK_RAWVIDEO=""
 #ALIASES += DEPRECATED_1_2_10="@deprecated Deprecated since 3.0, DALi version 1.2.10"
 #ALIASES += DEPRECATED_1_2="@deprecated Deprecated since 4.0, DALi version 1.2"
 #ALIASES += DEPRECATED_1_3="@deprecated Deprecated since 5.0, DALi version 1.3"
-#ALIASES += DEPRECATED_1_4="@deprecated Deprecated since 6.0, DALi version 1.4"
+#ALIASES += DEPRECATED_1_3_39="@deprecated Deprecated since 5.5, DALi version 1.3.39"
+#ALIASES += DEPRECATED_1_3_51="@deprecated Deprecated since 5.5, DALi version 1.3.51"
+#ALIASES += DEPRECATED_1_4="@deprecated Deprecated since 5.5, DALi version 1.4"
 
 #ALIASES += PLATFORM="@platform"
 #ALIASES += PRIVLEVEL_PLATFORM="\par Privilege Level:\n platform"
index 37def2b..1a2ec4b 100755 (executable)
@@ -185,6 +185,11 @@ Dali::TypeInfo ControlWrapper::GetTypeInfo()
   return DevelCustomActor::GetTypeInfo(Self());
 }
 
+void ControlWrapper::EmitKeyInputFocusSignal( bool focusGained )
+{
+  Control::EmitKeyInputFocusSignal( focusGained );
+}
+
 } // namespace Internal
 
 } // namespace Toolkit
index 115156e..25be5fa 100755 (executable)
@@ -47,6 +47,8 @@ devel_api_src_files = \
   $(devel_api_src_dir)/layouting/layout-transition-data.cpp \
   $(devel_api_src_dir)/scripting/script.cpp \
   $(devel_api_src_dir)/styling/style-manager-devel.cpp \
+  $(devel_api_src_dir)/text/bitmap-font.cpp \
+  $(devel_api_src_dir)/text/text-utils-devel.cpp \
   $(devel_api_src_dir)/transition-effects/cube-transition-cross-effect.cpp \
   $(devel_api_src_dir)/transition-effects/cube-transition-effect.cpp \
   $(devel_api_src_dir)/transition-effects/cube-transition-fold-effect.cpp \
@@ -182,7 +184,9 @@ devel_api_text_controls_header_files = \
   $(devel_api_src_dir)/controls/text-controls/text-style-properties-devel.h
 
 devel_api_text_header_files = \
-  $(devel_api_src_dir)/text/text-enumerations-devel.h
+  $(devel_api_src_dir)/text/text-enumerations-devel.h \
+  $(devel_api_src_dir)/text/bitmap-font.h \
+  $(devel_api_src_dir)/text/text-utils-devel.h
 
 devel_api_tool_bar_header_files = \
   $(devel_api_src_dir)/controls/tool-bar/tool-bar.h
diff --git a/dali-toolkit/devel-api/text/bitmap-font.cpp b/dali-toolkit/devel-api/text/bitmap-font.cpp
new file mode 100755 (executable)
index 0000000..1e0e9c6
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// FILE HEADER
+#include <dali-toolkit/devel-api/text/bitmap-font.h>
+
+// EXTERNAL INCLUDE
+#include <dali/public-api/common/dali-vector.h>
+#include <dali/devel-api/text-abstraction/bitmap-font.h>
+
+// INTERNAL INCLUDE
+#include <dali-toolkit/internal/text/character-set-conversion.h>
+#include <dali-toolkit/internal/text/text-definitions.h>
+
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+using namespace Text;
+namespace DevelText
+{
+
+Glyph::Glyph()
+: url{},
+  utf8{ 0u },
+  ascender{ 0.f },
+  descender{ 0.f }
+{}
+
+Glyph::~Glyph()
+{}
+
+BitmapFontDescription::BitmapFontDescription()
+: glyphs{},
+  name{},
+  underlinePosition{ 0.f },
+  underlineThickness{ 1.f }
+{}
+
+BitmapFontDescription::~BitmapFontDescription()
+{}
+
+void CreateBitmapFont( const BitmapFontDescription& description, TextAbstraction::BitmapFont& bitmapFont )
+{
+  bitmapFont.glyphs.reserve( description.glyphs.size() );
+  bitmapFont.name = description.name;
+  bitmapFont.underlinePosition = description.underlinePosition;
+  bitmapFont.underlineThickness = description.underlineThickness;
+
+  for( const auto& glyph : description.glyphs )
+  {
+    // 1) Convert to utf32
+    Vector<Character> utf32;
+    utf32.Resize( glyph.utf8.size() );
+
+    const uint32_t numberOfCharacters = ( glyph.utf8.size() == 0 ) ? 0 :
+        Text::Utf8ToUtf32( reinterpret_cast<const uint8_t* const>( glyph.utf8.c_str() ),
+                           glyph.utf8.size(),
+                           &utf32[0u] );
+    utf32.Resize( numberOfCharacters );
+
+    TextAbstraction::BitmapGlyph bitmapGlyph( glyph.url, utf32[0u], glyph.ascender, glyph.descender );
+
+    bitmapFont.glyphs.push_back( std::move( bitmapGlyph ) );
+  }
+}
+
+} // namespace DevelText
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/devel-api/text/bitmap-font.h b/dali-toolkit/devel-api/text/bitmap-font.h
new file mode 100755 (executable)
index 0000000..ca068b4
--- /dev/null
@@ -0,0 +1,107 @@
+#ifndef DALI_TOOLKIT_FONT_BITMAP_DEVEL_H
+#define DALI_TOOLKIT_FONT_BITMAP_DEVEL_H
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
+#include <dali-toolkit/public-api/dali-toolkit-common.h>
+#include <string>
+
+namespace Dali
+{
+
+namespace TextAbstraction
+{
+// Forward declarations
+struct BitmapFont;
+}
+
+namespace Toolkit
+{
+
+namespace DevelText
+{
+
+/**
+ * @brief Struct that stores the needed info to create a bitmap glyph.
+ */
+
+struct DALI_TOOLKIT_API Glyph
+{
+  /**
+   * @brief Default constructor.
+   *
+   * Initialize the members to its defaults.
+   */
+  Glyph();
+
+  /**
+   * @brief Default destructor.
+   */
+  ~Glyph();
+
+  std::string url;  ///< The url of the glyph.
+  std::string utf8; ///< the glyph encoded in utf8
+  float ascender;   ///< The ascender. The distance from the base line to the top of the glyph.
+  float descender;  ///< The descender. The distance from the base line to the bottom of the glyph.
+};
+
+/**
+ * @brief Describes a bitmap font.
+ */
+struct DALI_TOOLKIT_API BitmapFontDescription
+{
+  /**
+   * @brief Default constructor.
+   *
+   * Initialize the members to its defaults.
+   */
+  BitmapFontDescription();
+
+  /**
+   * @brief Default destructor.
+   */
+  ~BitmapFontDescription();
+
+  std::vector<Glyph> glyphs; ///< Vector of glyphs.
+  std::string name;          ///< Name of the font.
+  float underlinePosition;   ///< The position of the underline from the base line.
+  float underlineThickness;  ///< The thickness of the underline.
+};
+
+/**
+ * @brief Creates a bitmap font with the given description.
+ *
+ * The @p bitmapFont output can be passed to the FontClient::GetFontId()
+ * method to load the font and get an Id.
+ *
+ * @param[in] description The description of the bitmap font.
+ * @param[out] bitmapFont A bitmap font.
+ *
+ * @note If the @e ascender and @e descender of the glyphs are zero, the @e descender value will be left as zero and all the bitmaps will be loaded to find out the @e ascender value.
+ */
+DALI_TOOLKIT_API void CreateBitmapFont( const BitmapFontDescription& description, TextAbstraction::BitmapFont& bitmapFont );
+
+} // namespace DevelText
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_UTILS_DEVEL_H
diff --git a/dali-toolkit/devel-api/text/text-utils-devel.cpp b/dali-toolkit/devel-api/text/text-utils-devel.cpp
new file mode 100755 (executable)
index 0000000..3a286ad
--- /dev/null
@@ -0,0 +1,1360 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// FILE HEADER
+#include <dali-toolkit/devel-api/text/text-utils-devel.h>
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/text-abstraction/font-client.h>
+#include <dali/devel-api/text-abstraction/text-renderer.h>
+#include <dali/devel-api/text-abstraction/text-renderer-layout-helper.h>
+#include <dali/integration-api/debug.h>
+#include <dali/devel-api/scripting/enum-helper.h>
+#include <cstring>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/bidirectional-support.h>
+#include <dali-toolkit/internal/text/character-set-conversion.h>
+#include <dali-toolkit/internal/text/color-segmentation.h>
+#include <dali-toolkit/internal/text/layouts/layout-engine.h>
+#include <dali-toolkit/internal/text/layouts/layout-parameters.h>
+#include <dali-toolkit/internal/text/logical-model-impl.h>
+#include <dali-toolkit/internal/text/markup-processor.h>
+#include <dali-toolkit/internal/text/multi-language-support.h>
+#include <dali-toolkit/internal/text/segmentation.h>
+#include <dali-toolkit/internal/text/shaper.h>
+#include <dali-toolkit/internal/text/text-enumerations-impl.h>
+#include <dali-toolkit/internal/text/text-font-style.h>
+#include <dali-toolkit/internal/text/visual-model-impl.h>
+
+namespace Dali
+{
+
+using namespace TextAbstraction;
+
+namespace Toolkit
+{
+using namespace Text;
+
+namespace DevelText
+{
+
+namespace Layout
+{
+
+/**
+ * @brief The text's layout.
+ */
+enum Type
+{
+  SINGLELINE, ///< The text is laid out on a single line.
+  MULTILINE,  ///< The text is laid out in multiple lines.
+  CIRCULAR,   ///< The text is laid out on a single line following a circular path.
+};
+
+} // namespace Layout
+
+namespace CircularAlignment
+{
+
+/**
+ * @brief The enumerations for the circular alignment.
+ */
+enum Type
+{
+  BEGIN,  ///< The text is aligned to the @p begin angle of the arc (or to the @p begin+increment if it's a RTL text).
+  CENTER, ///< The text is centered within the arc.
+  END,    ///< The text is aligned to the @p begin+increment angle of the arc (or to the @p begin if it's a RTL text).
+};
+
+} // namespace CircularAlignment
+
+const float TO_POINT_26_DOT_6 = 64.f;
+const float TO_FLOAT = 1.f / 255.f;
+const float TO_UCHAR = 255.f;
+const bool RTL = true;
+const float TWO_PI = 2.f * Dali::Math::PI; ///< 360 degrees in radians
+const float RAD_135 = Math::PI_2 + Math::PI_4; ///< 135 degrees in radians;
+const float RAD_225 = RAD_135    + Math::PI_2; ///< 225 degrees in radians;
+const float RAD_270 = 3.f * Math::PI_2;        ///< 270 degrees in radians;
+const float RAD_315 = RAD_225    + Math::PI_2; ///< 315 degrees in radians;
+
+DALI_ENUM_TO_STRING_TABLE_BEGIN( LAYOUT_TYPE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelText::Layout, SINGLELINE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelText::Layout, MULTILINE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelText::Layout, CIRCULAR )
+DALI_ENUM_TO_STRING_TABLE_END( LAYOUT_TYPE )
+
+DALI_ENUM_TO_STRING_TABLE_BEGIN( CIRCULAR_ALIGNMENT_TYPE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelText::CircularAlignment, BEGIN )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelText::CircularAlignment, CENTER )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelText::CircularAlignment, END )
+DALI_ENUM_TO_STRING_TABLE_END( CIRCULAR_ALIGNMENT_TYPE )
+
+bool GetLayoutEnumeration(const Property::Value& propertyValue, DevelText::Layout::Type& layout)
+{
+  return Scripting::GetEnumerationProperty(propertyValue, LAYOUT_TYPE_TABLE, LAYOUT_TYPE_TABLE_COUNT, layout);
+}
+
+bool GetCircularAlignmentEnumeration(const Property::Value& propertyValue, DevelText::CircularAlignment::Type& circularAlignment)
+{
+  return Scripting::GetEnumerationProperty(propertyValue, CIRCULAR_ALIGNMENT_TYPE_TABLE, CIRCULAR_ALIGNMENT_TYPE_TABLE_COUNT, circularAlignment);
+}
+
+Devel::PixelBuffer Render( const RendererParameters& textParameters, Vector<EmbeddedItemInfo>& embeddedItemLayout )
+{
+  if( textParameters.text.empty() )
+  {
+    Dali::Devel::PixelBuffer pixelBuffer = Dali::Devel::PixelBuffer::New( textParameters.textWidth,
+                                                                          textParameters.textHeight,
+                                                                          Dali::Pixel::RGBA8888 );
+
+    const unsigned int bufferSize = textParameters.textWidth * textParameters.textHeight * Dali::Pixel::GetBytesPerPixel(Dali::Pixel::RGBA8888);
+    unsigned char* buffer = pixelBuffer.GetBuffer();
+    memset(buffer, 0, bufferSize);
+
+    return pixelBuffer;
+  }
+
+  MultilanguageSupport multilanguageSupport = MultilanguageSupport::Get();
+  FontClient fontClient = FontClient::Get();
+  MetricsPtr metrics;
+  Text::Layout::Engine layoutEngine;                  ///< The layout engine.
+  LogicalModelPtr logicalModel = LogicalModel::New(); ///< Pointer to the logical model.
+  VisualModelPtr visualModel = VisualModel::New();    ///< Pointer to the visual model.
+  Vector<ColorBlendingMode> blendingMode;             ///< How embedded items and bitmap font glyphs are blended with color text.
+  Vector<bool> isEmoji;                               ///< Whether the glyph is an emoji.
+
+  // Use this to access FontClient i.e. to get down-scaled Emoji metrics.
+  metrics = Metrics::New( fontClient );
+  layoutEngine.SetMetrics( metrics );
+
+  TextAbstraction::TextRenderer::Parameters rendererParameters( visualModel->mGlyphs,
+                                                                visualModel->mGlyphPositions,
+                                                                visualModel->mColors,
+                                                                visualModel->mColorIndices,
+                                                                blendingMode,
+                                                                isEmoji );
+
+  rendererParameters.width = textParameters.textWidth;
+  rendererParameters.height = textParameters.textHeight;
+  rendererParameters.pixelFormat = TextAbstraction::TextRenderer::Parameters::RGBA8888; // @note: At the moment all textures are generated RGBA8888
+
+  Vector<Character>& utf32Characters = logicalModel->mText;                                             // Characters encoded in utf32.
+  Vector<Character> mirroredUtf32Characters;                                                             // The utf32Characters Characters but mirrored if there are RTL text.
+  Vector<LineBreakInfo>& lineBreakInfo = logicalModel->mLineBreakInfo;                                  // The line break info.
+  Vector<ScriptRun>& scripts = logicalModel->mScriptRuns;                                               // Charactes's script.
+  Vector<FontDescriptionRun>& fontDescriptionRuns = logicalModel->mFontDescriptionRuns;                 // Desired font descriptions.
+  Vector<FontRun>& validFonts = logicalModel->mFontRuns;                                                // Validated fonts.
+  Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo = logicalModel->mBidirectionalParagraphInfo; // The bidirectional info per paragraph.
+  Vector<BidirectionalLineInfoRun>& bidirectionalLineInfo = logicalModel->mBidirectionalLineInfo;       // The bidirectional info per line.
+  Vector<CharacterDirection>& directions = logicalModel->mCharacterDirections;                          // Character's directions.
+  Vector<ColorRun>& colorRuns = logicalModel->mColorRuns;                                               // colors of the text.
+
+  Vector<CharacterIndex>& glyphsToCharacters = visualModel->mGlyphsToCharacters;                        // Glyphs to character map.
+  Vector<GlyphIndex>& charactersToGlyph = visualModel->mCharactersToGlyph;                              // Characters to glyphs map.
+  Vector<Length>& charactersPerGlyph = visualModel->mCharactersPerGlyph;                                // Number of characters per glyph.
+  Vector<Length>& glyphsPerCharacter = visualModel->mGlyphsPerCharacter;                                // The number of glyphs that are shaped.
+  Vector<LineRun>& lines = visualModel->mLines;                                                         // The laid out lines.
+
+  Vector<GlyphIndex> newParagraphGlyphs;                   // Glyphs for the new paragraph characters.
+
+  // the default font's description.
+  FontDescription defaultFontDescription;
+  PointSize26Dot6 defaultPointSize = FontClient::DEFAULT_POINT_SIZE;
+
+  Length numberOfCharacters = 0u;                          // The number of characters (not glyphs!).
+  bool isTextMirrored = false;                             // Whether the text has been mirrored.
+
+  const uint8_t* utf8 = NULL;                              // pointer to the first character of the text (encoded in utf8)
+  Length textSize = 0u;                                    // The length of the utf8 string.
+
+  ////////////////////////////////////////////////////////////////////////////////
+  // Process the markup string if the mark-up processor is enabled.
+  ////////////////////////////////////////////////////////////////////////////////
+
+  MarkupProcessData markupProcessData( colorRuns,
+                                       fontDescriptionRuns,
+                                       logicalModel->mEmbeddedItems );
+
+  if (textParameters.markupEnabled)
+  {
+    ProcessMarkupString(textParameters.text, markupProcessData);
+    textSize = markupProcessData.markupProcessedText.size();
+
+    // This is a bit horrible but std::string returns a (signed) char*
+    utf8 = reinterpret_cast<const uint8_t*>(markupProcessData.markupProcessedText.c_str());
+  }
+  else
+  {
+    textSize = textParameters.text.size();
+
+    // This is a bit horrible but std::string returns a (signed) char*
+    utf8 = reinterpret_cast<const uint8_t*>(textParameters.text.c_str());
+  }
+
+  ////////////////////////////////////////////////////////////////////////////////
+  // Convert from utf8 to utf32
+  ////////////////////////////////////////////////////////////////////////////////
+
+  utf32Characters.Resize(textSize);
+
+  // Transform a text array encoded in utf8 into an array encoded in utf32.
+  // It returns the actual number of characters.
+  numberOfCharacters = Utf8ToUtf32( utf8, textSize, utf32Characters.Begin() );
+  utf32Characters.Resize( numberOfCharacters );
+
+  ////////////////////////////////////////////////////////////////////////////////
+  // Retrieve the Line and Word Break Info.
+  ////////////////////////////////////////////////////////////////////////////////
+
+  lineBreakInfo.Resize( numberOfCharacters, LINE_NO_BREAK );
+
+  SetLineBreakInfo( utf32Characters,
+                    0u,
+                    numberOfCharacters,
+                    lineBreakInfo );
+
+  ////////////////////////////////////////////////////////////////////////////////
+  // Retrieve the script runs.
+  ////////////////////////////////////////////////////////////////////////////////
+
+  multilanguageSupport.SetScripts( utf32Characters,
+                                   0u,
+                                   numberOfCharacters,
+                                   scripts );
+
+  // Check if there are emojis.
+  // If there are an RGBA8888 pixel format is needed.
+  for( const auto& run : scripts )
+  {
+    if( run.script == TextAbstraction::Script::EMOJI )
+    {
+      rendererParameters.pixelFormat = TextAbstraction::TextRenderer::Parameters::RGBA8888;
+      break;
+    }
+  }
+
+  ////////////////////////////////////////////////////////////////////////////////
+  // Retrieve the font runs.
+  ////////////////////////////////////////////////////////////////////////////////
+
+  // Set the description font run with the given text parameters.
+  FontDescriptionRun fontDescriptionRun;
+  fontDescriptionRun.characterRun.characterIndex = 0u;
+  fontDescriptionRun.characterRun.numberOfCharacters = numberOfCharacters;
+
+  fontDescriptionRun.familyLength = 0u;
+  fontDescriptionRun.familyName = nullptr;
+  fontDescriptionRun.familyDefined = !textParameters.fontFamily.empty();
+  if( fontDescriptionRun.familyDefined )
+  {
+    // The allocated memory will be freed when the logical model is destroyed.
+    fontDescriptionRun.familyLength = textParameters.fontFamily.size();
+    fontDescriptionRun.familyName = new char[fontDescriptionRun.familyLength];
+    memcpy( fontDescriptionRun.familyName, textParameters.fontFamily.c_str(), fontDescriptionRun.familyLength );
+  }
+
+  fontDescriptionRun.weightDefined = !textParameters.fontWeight.empty();
+  if( fontDescriptionRun.weightDefined )
+  {
+    fontDescriptionRun.weight = StringToWeight( textParameters.fontWeight.c_str() );
+  }
+
+  fontDescriptionRun.widthDefined = !textParameters.fontWidth.empty();
+  if( fontDescriptionRun.widthDefined )
+  {
+    fontDescriptionRun.width = StringToWidth( textParameters.fontWidth.c_str() );
+  }
+
+  fontDescriptionRun.slantDefined = !textParameters.fontSlant.empty();
+  if( fontDescriptionRun.slantDefined )
+  {
+    fontDescriptionRun.slant = StringToSlant( textParameters.fontSlant.c_str() );
+  }
+
+  fontDescriptionRun.sizeDefined = !EqualsZero( textParameters.fontSize );
+  if( fontDescriptionRun.sizeDefined )
+  {
+    fontDescriptionRun.size = static_cast<unsigned int>( textParameters.fontSize * TO_POINT_26_DOT_6 );
+  }
+
+  fontDescriptionRuns.PushBack( fontDescriptionRun );
+
+  // Validates the fonts. If there is a character with no assigned font it sets a default one.
+  // After this call, fonts are validated.
+  multilanguageSupport.ValidateFonts( utf32Characters,
+                                      scripts,
+                                      fontDescriptionRuns,
+                                      defaultFontDescription,
+                                      defaultPointSize,
+                                      0u,
+                                      numberOfCharacters,
+                                      validFonts );
+
+  ////////////////////////////////////////////////////////////////////////////////
+  // Retrieve the Bidirectional info.
+  ////////////////////////////////////////////////////////////////////////////////
+
+  bidirectionalInfo.Reserve( 1u );
+
+  SetBidirectionalInfo( utf32Characters,
+                        scripts,
+                        lineBreakInfo,
+                        0u,
+                        numberOfCharacters,
+                        bidirectionalInfo );
+
+  const bool hasBidirectionalText = 0u != bidirectionalInfo.Count();
+  if( hasBidirectionalText )
+  {
+    // Only set the character directions if there is right to left characters.
+    GetCharactersDirection( bidirectionalInfo,
+                            numberOfCharacters,
+                            0u,
+                            numberOfCharacters,
+                            directions );
+
+    // This paragraph has right to left text. Some characters may need to be mirrored.
+    // TODO: consider if the mirrored string can be stored as well.
+
+    isTextMirrored = GetMirroredText( utf32Characters,
+                                      directions,
+                                      bidirectionalInfo,
+                                      0u,
+                                      numberOfCharacters,
+                                      mirroredUtf32Characters );
+  }
+
+  ////////////////////////////////////////////////////////////////////////////////
+  // Retrieve the glyphs. Text shaping
+  ////////////////////////////////////////////////////////////////////////////////
+
+  const Vector<Character>& textToShape = isTextMirrored ? mirroredUtf32Characters : utf32Characters;
+
+  newParagraphGlyphs.Reserve( 1u );
+
+  // Shapes the text.
+  ShapeText( textToShape,
+             lineBreakInfo,
+             scripts,
+             validFonts,
+             0u,
+             0u,
+             numberOfCharacters,
+             rendererParameters.glyphs,
+             glyphsToCharacters,
+             charactersPerGlyph,
+             newParagraphGlyphs );
+
+  // Create the 'number of glyphs' per character and the glyph to character conversion tables.
+  visualModel->CreateGlyphsPerCharacterTable( 0u, 0u, numberOfCharacters );
+  visualModel->CreateCharacterToGlyphTable( 0u, 0u, numberOfCharacters );
+
+  const Length numberOfGlyphs = rendererParameters.glyphs.Count();
+
+  // Once the text has been shaped and the glyphs created it's possible to replace the font id of those glyphs
+  // that represent an image or an item and create the embedded item layout info.
+  // Note: the position of the embedded item can't be set until the text is laid-out.
+  embeddedItemLayout.Reserve( logicalModel->mEmbeddedItems.Count() );
+  for( const auto& item : logicalModel->mEmbeddedItems )
+  {
+    // Get the glyph that matches with the character index.
+    const GlyphIndex glyphIndex = visualModel->mCharactersToGlyph[item.characterIndex];
+    GlyphInfo& glyph = rendererParameters.glyphs[glyphIndex];
+
+    glyph.fontId = 0u;
+    Pixel::Format pixelFormat = Pixel::A8;
+    TextAbstraction::FontClient::EmbeddedItemDescription description = { std::string( item.url, item.urlLength ), item.width, item.height, item.colorBlendingMode };
+    glyph.index = fontClient.CreateEmbeddedItem( description, pixelFormat ); // Set here an index to an item.
+
+    if( ( Pixel::RGBA8888 == pixelFormat ) || ( Pixel::BGRA8888 == pixelFormat ) )
+    {
+      rendererParameters.pixelFormat = TextAbstraction::TextRenderer::Parameters::RGBA8888;
+    }
+
+    // If the url is empty the item is going to be added after the text is rendered. It's needed to store the layout here.
+    if( description.url.empty() )
+    {
+      EmbeddedItemInfo embeddedInfo =
+      {
+        item.characterIndex,
+        glyphIndex,
+        Vector2::ZERO,
+        Size( static_cast<float>( item.width ), static_cast<float>( item.height ) ),
+        Size( static_cast<float>( item.width ), static_cast<float>( item.height ) ),
+        Degree( 0.f ),
+        item.colorBlendingMode
+      };
+
+      embeddedItemLayout.PushBack( embeddedInfo );
+    }
+  }
+
+  ////////////////////////////////////////////////////////////////////////////////
+  // Retrieve the glyph's metrics.
+  ////////////////////////////////////////////////////////////////////////////////
+
+  metrics->GetGlyphMetrics( rendererParameters.glyphs.Begin(), numberOfGlyphs );
+
+  ////////////////////////////////////////////////////////////////////////////////
+  // Set the color runs in glyphs.
+  ////////////////////////////////////////////////////////////////////////////////
+
+  SetColorSegmentationInfo( colorRuns,
+                            charactersToGlyph,
+                            glyphsPerCharacter,
+                            0u,
+                            0u,
+                            numberOfCharacters,
+                            visualModel->mColors,
+                            visualModel->mColorIndices );
+
+  // Insert the default color at the beginning of the vector.
+  visualModel->mColors.Insert( visualModel->mColors.Begin(),textParameters.textColor );
+
+  // Set how the embedded items are blended with text color.
+  blendingMode.Resize( numberOfGlyphs, textParameters.isTextColorSet ? ColorBlendingMode::MULTIPLY : ColorBlendingMode::NONE );
+
+  if( !textParameters.isTextColorSet )
+  {
+    // Traverse the color runs.
+    for( const auto& run : colorRuns )
+    {
+      const GlyphIndex firstGlyph = visualModel->mCharactersToGlyph[run.characterRun.characterIndex];
+      const CharacterIndex lastCharacter = run.characterRun.characterIndex + run.characterRun.numberOfCharacters - 1u;
+      const GlyphIndex lastGlyphPlusOne = visualModel->mCharactersToGlyph[lastCharacter] + visualModel->mGlyphsPerCharacter[lastCharacter];
+
+      for( GlyphIndex index = firstGlyph; index < lastGlyphPlusOne; ++index )
+      {
+        blendingMode[index] = ColorBlendingMode::MULTIPLY;
+      }
+    }
+  }
+
+  // Traverse the embedded items and update the blending mode vector.
+  for( const auto& item : logicalModel->mEmbeddedItems )
+  {
+    const GlyphIndex glyphIndex = visualModel->mCharactersToGlyph[item.characterIndex];
+    blendingMode[glyphIndex] = item.colorBlendingMode;
+  }
+
+  ////////////////////////////////////////////////////////////////////////////////
+  // Set the isEmoji Vector
+  ////////////////////////////////////////////////////////////////////////////////
+
+  isEmoji.Resize( numberOfGlyphs, false );
+
+  for( const auto& run : scripts )
+  {
+    if( run.script == TextAbstraction::Script::EMOJI )
+    {
+      const GlyphIndex firstGlyph = visualModel->mCharactersToGlyph[run.characterRun.characterIndex];
+      const CharacterIndex lastCharacter = run.characterRun.characterIndex + run.characterRun.numberOfCharacters - 1u;
+      const GlyphIndex lastGlyphPlusOne = visualModel->mCharactersToGlyph[lastCharacter] + visualModel->mGlyphsPerCharacter[lastCharacter];
+
+      for( GlyphIndex index = firstGlyph; index < lastGlyphPlusOne; ++index )
+      {
+        isEmoji[index] = true;
+      }
+    }
+  }
+
+  ////////////////////////////////////////////////////////////////////////////////
+  // Layout the text.
+  ////////////////////////////////////////////////////////////////////////////////
+
+  // Sets the alignment
+  HorizontalAlignment::Type horizontalAlignment = Toolkit::HorizontalAlignment::CENTER;
+  HorizontalAlignment::Type horizontalCircularAlignment = Toolkit::HorizontalAlignment::CENTER;
+  VerticalAlignment::Type verticalAlignment = VerticalAlignment::CENTER;
+  Layout::Type layout = Layout::SINGLELINE;
+  CircularAlignment::Type circularAlignment = CircularAlignment::BEGIN;
+
+  Property::Value horizontalAlignmentStr( textParameters.horizontalAlignment );
+  GetHorizontalAlignmentEnumeration( horizontalAlignmentStr, horizontalAlignment );
+  horizontalCircularAlignment = horizontalAlignment;
+
+  Property::Value verticalAlignmentStr( textParameters.verticalAlignment );
+  GetVerticalAlignmentEnumeration( verticalAlignmentStr, verticalAlignment );
+
+  Property::Value layoutStr( textParameters.layout );
+  GetLayoutEnumeration( layoutStr, layout );
+
+  Property::Value circularAlignmentStr( textParameters.circularAlignment );
+  GetCircularAlignmentEnumeration( circularAlignmentStr, circularAlignment );
+
+  // Whether the layout is multi-line.
+  const Text::Layout::Engine::Type horizontalLayout = ( Layout::MULTILINE == layout ) ? Text::Layout::Engine::MULTI_LINE_BOX : Text::Layout::Engine::SINGLE_LINE_BOX;
+  layoutEngine.SetLayout( horizontalLayout ); // TODO: multi-line.
+
+
+  // Whether the layout is circular.
+  const bool isCircularTextLayout = (Layout::CIRCULAR == layout);
+  const bool isClockwise = isCircularTextLayout && ( 0.f < textParameters.incrementAngle );
+
+  // Calculates the max ascender or the max descender.
+  // Is used to calculate the radius of the base line of the text.
+  float maxAscenderDescender = 0.f;
+  if( isCircularTextLayout )
+  {
+    FontId currentFontId = 0u;
+    for( const auto& glyph : rendererParameters.glyphs )
+    {
+      if( currentFontId != glyph.fontId )
+      {
+        currentFontId = glyph.fontId;
+        FontMetrics metrics;
+        fontClient.GetFontMetrics(currentFontId, metrics);
+        maxAscenderDescender = std::max( maxAscenderDescender, isClockwise ? metrics.ascender : metrics.descender );
+      }
+    }
+  }
+  const unsigned int radius = textParameters.radius - static_cast<unsigned int>( maxAscenderDescender );
+
+  // Convert CircularAlignment to HorizontalAlignment.
+  if( isCircularTextLayout )
+  {
+    switch( circularAlignment )
+    {
+      case CircularAlignment::BEGIN:
+      {
+        horizontalCircularAlignment = Toolkit::HorizontalAlignment::BEGIN;
+        break;
+      }
+      case CircularAlignment::CENTER:
+      {
+        horizontalCircularAlignment = Toolkit::HorizontalAlignment::CENTER;
+        break;
+      }
+      case CircularAlignment::END:
+      {
+        horizontalCircularAlignment = Toolkit::HorizontalAlignment::END;
+        break;
+      }
+    }
+  }
+
+  // Set the layout parameters.
+  Size textLayoutArea( static_cast<float>( textParameters.textWidth ),
+                     static_cast<float>( textParameters.textHeight ) );
+
+  if( isCircularTextLayout )
+  {
+    // In a circular layout, the length of the text area depends on the radius.
+    rendererParameters.radius = radius;
+    textLayoutArea.width = fabs( Radian( Degree( textParameters.incrementAngle ) ) * static_cast<float>( rendererParameters.radius ) );
+  }
+
+  Text::Layout::Parameters layoutParameters( textLayoutArea,
+                                       textToShape.Begin(),
+                                       lineBreakInfo.Begin(),
+                                       nullptr,
+                                       ( 0u != directions.Count() ) ? directions.Begin() : nullptr,
+                                       rendererParameters.glyphs.Begin(),
+                                       glyphsToCharacters.Begin(),
+                                       charactersPerGlyph.Begin(),
+                                       charactersToGlyph.Begin(),
+                                       glyphsPerCharacter.Begin(),
+                                       numberOfGlyphs,
+                                       isCircularTextLayout ? horizontalCircularAlignment : horizontalAlignment,
+                                       LineWrap::WORD,
+                                       0.f,
+                                       false,
+                                       false ); // Outline's width
+
+  // Resize the vector of positions to have the same size than the vector of glyphs.
+  rendererParameters.positions.Resize( numberOfGlyphs );
+
+  // Whether the last character is a new paragraph character.
+  layoutParameters.isLastNewParagraph = TextAbstraction::IsNewParagraph( textToShape[numberOfCharacters - 1u] );
+
+  // The initial glyph and the number of glyphs to layout.
+  layoutParameters.startGlyphIndex = 0u;
+  layoutParameters.numberOfGlyphs = numberOfGlyphs;
+  layoutParameters.startLineIndex = 0u;
+  layoutParameters.estimatedNumberOfLines = 1u;
+
+  // Update the visual model.
+  Size newLayoutSize;
+  bool isAutoScrollEnabled = false;
+  layoutEngine.LayoutText( layoutParameters,
+                           rendererParameters.positions,
+                           lines,
+                           newLayoutSize,
+                           textParameters.ellipsisEnabled,
+                           isAutoScrollEnabled );
+
+  ////////////////////////////////////////////////////////////////////////////////
+  // Reorder BiDirectional lines.
+  ////////////////////////////////////////////////////////////////////////////////
+
+  if( hasBidirectionalText )
+  {
+    // Reorder the line.
+    bidirectionalLineInfo.Reserve( 1u );
+
+    ReorderLines( bidirectionalInfo,
+                  0u,
+                  numberOfCharacters,
+                  lines,
+                  bidirectionalLineInfo );
+
+    // Set the bidirectional info per line into the layout parameters.
+    layoutParameters.lineBidirectionalInfoRunsBuffer = bidirectionalLineInfo.Begin();
+    layoutParameters.numberOfBidirectionalInfoRuns = bidirectionalLineInfo.Count();
+
+    // Re-layout the text. Reorder those lines with right to left characters.
+    layoutEngine.ReLayoutRightToLeftLines( layoutParameters,
+                                           0u,
+                                           numberOfCharacters,
+                                           rendererParameters.positions );
+  }
+
+  ////////////////////////////////////////////////////////////////////////////////
+  // Align the text.
+  ////////////////////////////////////////////////////////////////////////////////
+
+  // Retrieve the line of text to know the direction and the width. @todo multi-line
+  const LineRun& line = lines[0u];
+
+  if( isCircularTextLayout )
+  {
+    // Set the circular alignment.
+    rendererParameters.circularLayout = isClockwise ? TextRenderer::Parameters::CLOCKWISE : TextRenderer::Parameters::COUNTER_CLOCKWISE;
+
+    // Update the text's height to be used by the ellipsis code.
+    textLayoutArea.height = newLayoutSize.height;
+
+    // Set the size of the text laid out on a straight horizontal line.
+    rendererParameters.circularWidth = static_cast<unsigned int>( newLayoutSize.width );
+    rendererParameters.circularHeight = static_cast<unsigned int>( newLayoutSize.height );
+
+    // Calculate the center of the circular text according the horizontal and vertical alingments and the radius.
+    switch( horizontalAlignment )
+    {
+      case HorizontalAlignment::BEGIN:
+      {
+        rendererParameters.centerX = static_cast<int>(textParameters.radius);
+        break;
+      }
+      case HorizontalAlignment::CENTER:
+      {
+        rendererParameters.centerX = static_cast<int>( textParameters.textWidth / 2u );
+        break;
+      }
+      case HorizontalAlignment::END:
+      {
+        rendererParameters.centerX = static_cast<int>( textParameters.textWidth ) - static_cast<int>(textParameters.radius);
+        break;
+      }
+    }
+
+    switch( verticalAlignment )
+    {
+      case VerticalAlignment::TOP:
+      {
+        rendererParameters.centerY = static_cast<int>(textParameters.radius);
+        break;
+      }
+      case VerticalAlignment::CENTER:
+      {
+        rendererParameters.centerY = static_cast<int>( textParameters.textHeight / 2u );
+        break;
+      }
+      case VerticalAlignment::BOTTOM:
+      {
+        rendererParameters.centerY = static_cast<int>( textParameters.textHeight ) - static_cast<int>(textParameters.radius);
+        break;
+      }
+    }
+
+    // Calculate the beginning angle according with the given horizontal alignment.
+    const bool isRTL = RTL == line.direction;
+
+    CircularAlignment::Type alignment = circularAlignment;
+    if( isRTL )
+    {
+      // Swap the alignment type if the line is right to left.
+      switch( alignment )
+      {
+        case CircularAlignment::BEGIN:
+        {
+          alignment = CircularAlignment::END;
+          break;
+        }
+        case CircularAlignment::CENTER:
+        {
+          // Nothing to do.
+          break;
+        }
+        case CircularAlignment::END:
+        {
+          alignment = CircularAlignment::BEGIN;
+          break;
+        }
+      }
+    }
+
+    float angleOffset = 0.f;
+
+    switch( alignment )
+    {
+      case CircularAlignment::BEGIN:
+      {
+        angleOffset = 0.f;
+        break;
+      }
+      case CircularAlignment::CENTER:
+      {
+        const bool isNeg = textParameters.incrementAngle < 0.f;
+        const float textWidth = static_cast<float>( rendererParameters.circularWidth );
+        angleOffset = ( isNeg ? -0.5f : 0.5f ) * ( textLayoutArea.width - textWidth ) / static_cast<float>( radius );
+        break;
+      }
+      case CircularAlignment::END:
+      {
+        const bool isNeg = textParameters.incrementAngle < 0.f;
+        const float textWidth = static_cast<float>( rendererParameters.circularWidth );
+        angleOffset = ( isNeg ? -1.f : 1.f ) * ( textLayoutArea.width - textWidth ) / static_cast<float>( radius );
+        break;
+      }
+    }
+
+    // Update the beginning angle with the calculated offset.
+    rendererParameters.beginAngle = Radian( Degree( textParameters.beginAngle ) ) + angleOffset;
+
+    // Set the vertical position of the glyphs.
+    for( auto& position : rendererParameters.positions )
+    {
+      position.y = 0.f;
+    }
+  }
+  else
+  {
+    // Calculate the vertical offset according with the given alignment.
+    float penY = 0.f;
+
+    switch( verticalAlignment )
+    {
+      case VerticalAlignment::TOP:
+      {
+        penY = line.ascender;
+        break;
+      }
+      case VerticalAlignment::CENTER:
+      {
+        penY = line.ascender + 0.5f * ( textLayoutArea.height - ( line.ascender - line.descender ) );
+        break;
+      }
+      case VerticalAlignment::BOTTOM:
+      {
+        penY = textLayoutArea.height;
+        break;
+      }
+    }
+
+    // Calculate the horizontal offset according with the given alignment.
+  float alignmentOffset = 0.f;
+    layoutEngine.Align( textLayoutArea,
+                      0u,
+                      numberOfCharacters,
+                      horizontalAlignment,
+                      lines,
+                      alignmentOffset,
+                      Dali::LayoutDirection::LEFT_TO_RIGHT,
+                      false );
+
+    // Update the position of the glyphs with the calculated offsets.
+    for( auto& position : rendererParameters.positions )
+  {
+    position.x += line.alignmentOffset;
+    position.y = penY;
+  }
+  }
+
+  // Cairo adds the bearing to the position of the glyph
+  // that has already been added by the DALi's layout engine,
+  // so it's needed to be removed here.
+  for( unsigned int index = 0u; index < rendererParameters.glyphs.Count(); ++index )
+  {
+    const GlyphInfo& glyph = rendererParameters.glyphs[index];
+    Vector2& position = rendererParameters.positions[index];
+
+    position.x -= glyph.xBearing;
+  }
+
+  // Set the position of the embedded items (if there is any).
+  EmbeddedItemInfo* embeddedItemLayoutBuffer = embeddedItemLayout.Begin();
+
+  auto transformToArc = isClockwise ? &Dali::TextAbstraction::TransformToArcClockwise : &Dali::TextAbstraction::TransformToArcAntiClockwise;
+
+  for( Length index = 0u, endIndex = embeddedItemLayout.Count(); index < endIndex; ++index )
+  {
+    EmbeddedItemInfo& embeddedItem = *( embeddedItemLayoutBuffer + index );
+
+    embeddedItem.position = rendererParameters.positions[embeddedItem.glyphIndex];
+
+    if( isCircularTextLayout )
+    {
+      // Calculate the new position of the embedded item in the circular path.
+
+      // Center of the bitmap.
+      const float halfWidth = 0.5f * embeddedItem.size.width;
+      const float halfHeight = 0.5f * embeddedItem.size.height;
+      double centerX = static_cast<double>( embeddedItem.position.x + halfWidth );
+      double centerY = static_cast<double>(embeddedItem.position.y - halfHeight);
+
+      Dali::TextAbstraction::CircularTextParameters circularTextParameters;
+
+      circularTextParameters.radius = static_cast<double>( radius );
+      circularTextParameters.invRadius = 1.0 / circularTextParameters.radius;
+      circularTextParameters.beginAngle = static_cast<double>( -rendererParameters.beginAngle + Dali::Math::PI_2 );
+      circularTextParameters.centerX = 0.5f * static_cast<double>( textParameters.textWidth );
+      circularTextParameters.centerY = 0.5f * static_cast<double>( textParameters.textHeight );
+
+      // Calculate the rotation angle.
+      float radians = rendererParameters.beginAngle;
+      if( isClockwise )
+      {
+        radians += static_cast<float>( circularTextParameters.invRadius * centerX );
+        radians = -radians;
+      }
+      else
+      {
+        radians -= static_cast<float>( circularTextParameters.invRadius * centerX );
+        radians = -radians + Dali::Math::PI;
+      }
+      embeddedItem.angle = Degree( Radian( radians ) );
+
+      transformToArc( circularTextParameters, centerX, centerY );
+
+      // Recalculate the size of the embedded item after the rotation to position it correctly.
+      float width = embeddedItem.size.width;
+      float height = embeddedItem.size.height;
+
+      // Transform the input angle into the range [0..2PI]
+      radians = fmod( radians, TWO_PI );
+      radians += ( radians < 0.f ) ? TWO_PI : 0.f;
+
+      // Does the same operations than rotate by shear.
+      if( ( radians > Math::PI_4 ) && ( radians <= RAD_135 ) )
+      {
+        std::swap( width, height );
+        radians -= Math::PI_2;
+      }
+      else if( ( radians > RAD_135 ) && ( radians <= RAD_225 ) )
+      {
+        radians -= Math::PI;
+      }
+      else if( ( radians > RAD_225 ) && ( radians <= RAD_315 ) )
+      {
+        std::swap( width, height );
+        radians -= RAD_270;
+      }
+
+      if( fabs( radians ) > Dali::Math::MACHINE_EPSILON_10 )
+      {
+        const float angleSinus = fabs( sin( radians ) );
+        const float angleCosinus = cos( radians );
+
+        // Calculate the rotated image dimensions.
+        embeddedItem.rotatedSize.height = width * angleSinus + height * angleCosinus;
+        embeddedItem.rotatedSize.width = height * angleSinus + width * angleCosinus + 1.f;
+      }
+
+      embeddedItem.position.x = floor( static_cast<float>( centerX ) - 0.5f * embeddedItem.rotatedSize.width );
+      embeddedItem.position.y = floor( static_cast<float>( centerY ) - 0.5f * embeddedItem.rotatedSize.height );
+    }
+    else
+    {
+      embeddedItem.position.y -= embeddedItem.size.height;
+    }
+  }
+
+  ////////////////////////////////////////////////////////////////////////////////
+  // Ellipsis the text.
+  ////////////////////////////////////////////////////////////////////////////////
+
+  if( textParameters.ellipsisEnabled )
+  {
+    const LineRun& line = lines[0u]; // TODO: multi-line
+
+    if( line.ellipsis )
+    {
+      Length finalNumberOfGlyphs = 0u;
+
+      if( ( line.ascender - line.descender ) > textLayoutArea.height )
+      {
+        // The height of the line is bigger than the height of the text area.
+        // Show the ellipsis glyph even if it doesn't fit in the text area.
+        // If no text is rendered then issues are rised and it may be a while
+        // until is find out that the text area is too small.
+
+        // Get the first glyph which is going to be replaced and the ellipsis glyph.
+        GlyphInfo& glyphInfo = rendererParameters.glyphs[0u];
+        const GlyphInfo& ellipsisGlyph = fontClient.GetEllipsisGlyph( fontClient.GetPointSize( glyphInfo.fontId ) );
+
+        // Change the 'x' and 'y' position of the ellipsis glyph.
+        Vector2& position = rendererParameters.positions[0u];
+        position.x = ellipsisGlyph.xBearing;
+        position.y = textLayoutArea.height - ellipsisGlyph.yBearing;
+
+        // Replace the glyph by the ellipsis glyph.
+        glyphInfo = ellipsisGlyph;
+
+        // Set the final number of glyphs
+        finalNumberOfGlyphs = 1u;
+      }
+      else
+      {
+
+        // firstPenX, penY and firstPenSet are used to position the ellipsis glyph if needed.
+        float firstPenX = 0.f; // Used if rtl text is elided.
+        bool firstPenSet = false;
+
+        // Add the ellipsis glyph.
+        bool inserted = false;
+        float removedGlypsWidth = 0.f;
+        Length numberOfRemovedGlyphs = 0u;
+        if (line.glyphRun.numberOfGlyphs > 0u)
+        {
+          GlyphIndex index = line.glyphRun.numberOfGlyphs - 1u;
+
+          GlyphInfo* glyphs = rendererParameters.glyphs.Begin();
+          Vector2* glyphPositions = rendererParameters.positions.Begin();
+
+          float penY = 0.f;
+
+          // The ellipsis glyph has to fit in the place where the last glyph(s) is(are) removed.
+          while( !inserted )
+          {
+            const GlyphInfo& glyphToRemove = *( glyphs + index );
+
+            if( 0u != glyphToRemove.fontId )
+            {
+              // i.e. The font id of the glyph shaped from the '\n' character is zero.
+
+              // Need to reshape the glyph as the font may be different in size.
+              const GlyphInfo& ellipsisGlyph = fontClient.GetEllipsisGlyph( fontClient.GetPointSize( glyphToRemove.fontId ) );
+
+              if( !firstPenSet )
+              {
+                const Vector2& position = *( glyphPositions + index );
+
+                // Calculates the penY of the current line. It will be used to position the ellipsis glyph.
+                penY = position.y;
+
+                // Calculates the first penX which will be used if rtl text is elided.
+                firstPenX = position.x - glyphToRemove.xBearing;
+                if( firstPenX < -ellipsisGlyph.xBearing )
+                {
+                  // Avoids to exceed the bounding box when rtl text is elided.
+                  firstPenX = -ellipsisGlyph.xBearing;
+                }
+
+                removedGlypsWidth = -ellipsisGlyph.xBearing;
+
+                firstPenSet = true;
+              }
+
+              removedGlypsWidth += std::min( glyphToRemove.advance, ( glyphToRemove.xBearing + glyphToRemove.width ) );
+
+              // Calculate the width of the ellipsis glyph and check if it fits.
+              const float ellipsisGlyphWidth = ellipsisGlyph.width + ellipsisGlyph.xBearing;
+              if( ellipsisGlyphWidth < removedGlypsWidth )
+              {
+                GlyphInfo& glyphInfo = *( glyphs + index );
+                Vector2& position = *( glyphPositions + index );
+                position.x -= ( 0.f > glyphInfo.xBearing ) ? glyphInfo.xBearing : 0.f;
+
+                // Replace the glyph by the ellipsis glyph.
+                glyphInfo = ellipsisGlyph;
+
+                // Update the isEmoji vector
+                isEmoji[index] = false;
+
+                // Change the 'x' and 'y' position of the ellipsis glyph.
+
+                if( position.x > firstPenX )
+                {
+                  position.x = firstPenX + removedGlypsWidth - ellipsisGlyphWidth;
+                }
+
+                position.x += ellipsisGlyph.xBearing;
+                position.y = penY;
+
+                inserted = true;
+              }
+            }
+
+            if( !inserted )
+            {
+              if( index > 0u )
+              {
+                --index;
+              }
+              else
+              {
+                // No space for the ellipsis.
+                inserted = true;
+              }
+              ++numberOfRemovedGlyphs;
+            }
+
+            // Set the final number of glyphs
+            finalNumberOfGlyphs = line.glyphRun.numberOfGlyphs - numberOfRemovedGlyphs;
+          }
+        }
+
+        // Resize the number of glyphs/positions
+        rendererParameters.glyphs.Resize( finalNumberOfGlyphs );
+        rendererParameters.positions.Resize( finalNumberOfGlyphs );
+
+        // Remove from the embedded items those exceding the last laid out glyph.
+        embeddedItemLayout.Erase( std::remove_if( embeddedItemLayout.Begin(),
+                                                  embeddedItemLayout.End(),
+                                                  [finalNumberOfGlyphs]( const EmbeddedItemInfo& item )
+                                                  {
+                                                     return item.glyphIndex >= finalNumberOfGlyphs;
+                                                  } ),
+                                 embeddedItemLayout.End() );
+      }
+    }
+  }
+
+  ////////////////////////////////////////////////////////////////////////////////
+  // Render the text.
+  ////////////////////////////////////////////////////////////////////////////////
+
+  rendererParameters.width = textParameters.textWidth;
+  rendererParameters.height = textParameters.textHeight;
+
+  TextAbstraction::TextRenderer renderer = TextAbstraction::TextRenderer::Get();
+  return renderer.Render( rendererParameters );
+}
+
+Devel::PixelBuffer CreateShadow( const ShadowParameters& shadowParameters )
+{
+  // The size of the pixel data.
+  const int width = static_cast<int>(shadowParameters.input.GetWidth());
+  const int height = static_cast<int>(shadowParameters.input.GetHeight());
+
+  // The shadow's offset.
+  const int xOffset = static_cast<int>( shadowParameters.offset.x );
+  const int yOffset = static_cast<int>( shadowParameters.offset.y );
+
+  // The size in bytes of the pixel of the input's buffer.
+  const Pixel::Format inputFormat = shadowParameters.input.GetPixelFormat();
+  const unsigned int inputPixelSize = Pixel::GetBytesPerPixel( inputFormat );
+  const bool isA8 = Pixel::A8 == inputFormat;
+
+  // Creates the output pixel buffer.
+  Devel::PixelBuffer outputPixelBuffer = Devel::PixelBuffer::New(width, height, Pixel::RGBA8888);
+
+  // Clear the output buffer
+  unsigned char* outputPixelBufferPtr = outputPixelBuffer.GetBuffer();
+  memset(outputPixelBufferPtr, 0, width * height * Pixel::GetBytesPerPixel(Pixel::RGBA8888));
+
+  // Gets the buffer of the input pixel buffer.
+  const unsigned char* const inputPixelBuffer = shadowParameters.input.GetBuffer();
+
+  float textColor[4u];
+  if (isA8)
+  {
+    memcpy(textColor, shadowParameters.textColor.AsFloat(), 4u * sizeof(float));
+  }
+  const float* const shadowColor = shadowParameters.color.AsFloat();
+
+  // Traverse the input pixel buffer and write the text on the foreground and the shadow on the background.
+  for (int rowIndex = 0; rowIndex < height; ++rowIndex)
+  {
+    // Calculates the rowIndex to the input pixel buffer for the shadow and whether it's within the boundaries.
+    const int yOffsetIndex = rowIndex - yOffset;
+    const bool isValidRowIndex = ((yOffsetIndex >= 0) && (yOffsetIndex < height));
+
+    const int rows = rowIndex * width;
+    const int offsetRows = yOffsetIndex * width;
+    for (int columnIndex = 0; columnIndex < width; ++columnIndex)
+    {
+      // Index to the input buffer to retrieve the alpha value of the foreground text.
+      const unsigned int index = inputPixelSize * static_cast<unsigned int>(rows + columnIndex);
+
+      // Build the index to the input buffer to retrieve the alpha value of the background shadow.
+      unsigned int shadowIndex = 0u;
+      bool isValidShadowIndex = false;
+      if (isValidRowIndex)
+      {
+        const int xOffsetIndex = columnIndex - xOffset;
+        isValidShadowIndex = ((xOffsetIndex >= 0) && (xOffsetIndex < width));
+
+        if (isValidShadowIndex)
+        {
+          shadowIndex = inputPixelSize * static_cast<unsigned int>(offsetRows + xOffsetIndex);
+        }
+      }
+
+      // If the input buffer is an alpha mask, retrieve the values for the foreground text and the background shadow.
+      // If not retrieve the color.
+      float inputShadowOffsetAlphaValue = 1.f;
+      float inputAlphaValue = 1.f;
+      if (isA8)
+      {
+        // Retrieve the alpha value for the shadow.
+        inputShadowOffsetAlphaValue = isValidShadowIndex ? (static_cast<float>(*(inputPixelBuffer + shadowIndex)) / 255.f) : 0.f;
+
+        // Retrieve the alpha value for the text.
+        inputAlphaValue = static_cast<float>(*(inputPixelBuffer + index)) / 255.f;
+      }
+      else
+      {
+        // The input buffer is not an alpha mask. Retrieve the color.
+        textColor[0u] = TO_FLOAT * static_cast<float>( *(inputPixelBuffer + index + 0u) );
+        textColor[1u] = TO_FLOAT * static_cast<float>( *(inputPixelBuffer + index + 1u) );
+        textColor[2u] = TO_FLOAT * static_cast<float>( *(inputPixelBuffer + index + 2u) );
+        textColor[3u] = TO_FLOAT * static_cast<float>( *(inputPixelBuffer + index + 3u) );
+        inputAlphaValue = textColor[3u];
+        inputShadowOffsetAlphaValue = isValidShadowIndex ? TO_FLOAT * static_cast<float>( *(inputPixelBuffer + shadowIndex + 3u) ) : 0.f;
+      }
+
+      // Build the output color.
+      float outputColor[4u];
+
+      if( shadowParameters.blendShadow )
+      {
+        // Blend the shadow's color with the text's color on top
+        const float textAlpha = textColor[3u] * inputAlphaValue;
+        const float shadowAlpha = shadowColor[3u] * inputShadowOffsetAlphaValue;
+
+        // Blends the alpha.
+        outputColor[3u] = 1.f - ((1.f - textAlpha) * (1.f - shadowAlpha));
+        const bool isOutputAlphaZero = outputColor[3u] < Dali::Math::MACHINE_EPSILON_1000;
+        if( isOutputAlphaZero )
+        {
+          std::fill( outputColor, outputColor + 4u, 0.f );
+        }
+        else
+        {
+          // Blends the RGB components.
+          float shadowComponent = 0.f;
+          float textComponent = 0.f;
+
+          shadowComponent = shadowColor[0u] * inputShadowOffsetAlphaValue;
+          textComponent = textColor[0u] * inputAlphaValue;
+          outputColor[0u] =  (textComponent * textAlpha / outputColor[3u]) + (shadowComponent * shadowAlpha * (1.f - textAlpha) / outputColor[3u]);
+
+          shadowComponent = shadowColor[1u] * inputShadowOffsetAlphaValue;
+          textComponent = textColor[1u] * inputAlphaValue;
+          outputColor[1u] =  (textComponent * textAlpha / outputColor[3u]) + (shadowComponent * shadowAlpha * (1.f - textAlpha) / outputColor[3u]);
+
+          shadowComponent = shadowColor[2u] * inputShadowOffsetAlphaValue;
+          textComponent = textColor[2u] * inputAlphaValue;
+          outputColor[2u] =  (textComponent * textAlpha / outputColor[3u]) + (shadowComponent * shadowAlpha * (1.f - textAlpha) / outputColor[3u]);
+        }
+      }
+      else
+      {
+        // No blending!!!
+        std::fill( outputColor, outputColor + 4u, 0.f );
+
+        const float textAlpha = textColor[3u];
+        const float shadowAlpha = shadowColor[3u] * inputShadowOffsetAlphaValue;
+
+        // Write shadow first.
+        if( shadowAlpha > Dali::Math::MACHINE_EPSILON_1000 )
+        {
+          outputColor[0u] = shadowColor[0u] * inputShadowOffsetAlphaValue;
+          outputColor[1u] = shadowColor[1u] * inputShadowOffsetAlphaValue;
+          outputColor[2u] = shadowColor[2u] * inputShadowOffsetAlphaValue;
+          outputColor[3u] = shadowAlpha;
+        }
+
+        // Write character on top.
+        if( textAlpha > Dali::Math::MACHINE_EPSILON_1000 )
+        {
+          outputColor[0u] = textColor[0u];
+          outputColor[1u] = textColor[1u];
+          outputColor[2u] = textColor[2u];
+          outputColor[3u] = textAlpha;
+        }
+      }
+
+      // Write the color into the output pixel buffer.
+      const unsigned int outputIndex = 4u * (rows + columnIndex);
+      *(outputPixelBufferPtr + outputIndex + 0u) = static_cast<unsigned char>( TO_UCHAR * outputColor[0u] );
+      *(outputPixelBufferPtr + outputIndex + 1u) = static_cast<unsigned char>( TO_UCHAR * outputColor[1u] );
+      *(outputPixelBufferPtr + outputIndex + 2u) = static_cast<unsigned char>( TO_UCHAR * outputColor[2u] );
+      *(outputPixelBufferPtr + outputIndex + 3u) = static_cast<unsigned char>( TO_UCHAR * outputColor[3u] );
+    }
+  }
+
+  // Returns the pixel buffer.
+  return outputPixelBuffer;
+}
+
+Devel::PixelBuffer ConvertToRgba8888(Devel::PixelBuffer pixelBuffer, const Vector4& color, bool multiplyByAlpha)
+{
+  if (Dali::Pixel::A8 != pixelBuffer.GetPixelFormat())
+  {
+    // Does nothing.
+    return pixelBuffer;
+  }
+
+  const unsigned int width = pixelBuffer.GetWidth();
+  const unsigned int height = pixelBuffer.GetHeight();
+  Devel::PixelBuffer newPixelBuffer = Devel::PixelBuffer::New( width, height, Dali::Pixel::RGBA8888 );
+
+  unsigned char* dstBuffer = newPixelBuffer.GetBuffer();
+  const unsigned char* const srcBuffer = pixelBuffer.GetBuffer();
+
+  const unsigned char r = static_cast<unsigned char>( TO_UCHAR * color.r );
+  const unsigned char g = static_cast<unsigned char>( TO_UCHAR * color.g );
+  const unsigned char b = static_cast<unsigned char>( TO_UCHAR * color.b );
+
+  unsigned char dstColor[4];
+  for( unsigned int j = 0u; j < height; ++j )
+  {
+    const unsigned int lineIndex = j * width;
+    for( unsigned int i=0u; i < width; ++i )
+    {
+      const unsigned int srcIndex = lineIndex + i;
+
+      const float srcAlpha = static_cast<float>( *( srcBuffer + srcIndex ) );
+
+      if( multiplyByAlpha )
+      {
+        dstColor[0u] = static_cast<unsigned char>( srcAlpha * color.r );
+        dstColor[1u] = static_cast<unsigned char>( srcAlpha * color.g );
+        dstColor[2u] = static_cast<unsigned char>( srcAlpha * color.b );
+        dstColor[3u] = static_cast<unsigned char>( srcAlpha * color.a );
+      }
+      else
+      {
+        dstColor[0u] = r;
+        dstColor[1u] = g;
+        dstColor[2u] = b;
+        dstColor[3u] = static_cast<unsigned char>( srcAlpha );
+      }
+
+      const unsigned int dstIndex = srcIndex * 4u;
+      memcpy( dstBuffer + dstIndex, dstColor, 4u );
+    }
+  }
+
+  return newPixelBuffer;
+}
+
+void UpdateBuffer(Devel::PixelBuffer src, Devel::PixelBuffer dst, unsigned int x, unsigned int y, bool blend)
+{
+  const Dali::Pixel::Format pixelFormat = dst.GetPixelFormat();
+  if( src.GetPixelFormat() != pixelFormat )
+  {
+    DALI_LOG_ERROR("PixelBuffer::SetBuffer. The pixel format of the new data must be the same of the current pixel buffer.");
+    return;
+  }
+
+  const unsigned int srcWidth = src.GetWidth();
+  const unsigned int srcHeight = src.GetHeight();
+  const unsigned int dstWidth = dst.GetWidth();
+  const unsigned int dstHeight = dst.GetHeight();
+
+  if( ( x > dstWidth ) ||
+      ( y > dstHeight ) ||
+      ( x + srcWidth > dstWidth ) ||
+      ( y + srcHeight > dstHeight ) )
+  {
+    DALI_LOG_ERROR("PixelBuffer::SetBuffer. The source pixel buffer is out of the boundaries of the destination pixel buffer.");
+    return;
+  }
+
+  const unsigned int bytesPerPixel = Dali::Pixel::GetBytesPerPixel(pixelFormat);
+  const unsigned int alphaIndex = bytesPerPixel - 1u;
+
+  const unsigned char* const srcBuffer = src.GetBuffer();
+  unsigned char* dstBuffer = dst.GetBuffer();
+
+  if( !blend )
+  {
+    const unsigned int currentLineSize = dstWidth * bytesPerPixel;
+    const unsigned int newLineSize = srcWidth * bytesPerPixel;
+    unsigned char* currentBuffer = dstBuffer + (y * dstWidth + x) * bytesPerPixel;
+    for (unsigned int j = 0u; j < srcHeight; ++j)
+    {
+      memcpy(currentBuffer + j * currentLineSize, srcBuffer + j * newLineSize, newLineSize);
+    }
+  }
+  else
+  {
+    float outputColor[4u];
+
+    // Blend the src pixel buffer with the dst pixel buffer as background.
+    //
+    //  fgColor, fgAlpha, bgColor, bgAlpha
+    //
+    //  alpha = 1 - ( 1 - fgAlpha ) * ( 1 - bgAlpha )
+    //  color = ( fgColor * fgAlpha / alpha ) + ( bgColor * bgAlpha * ( 1 - fgAlpha ) / alpha )
+
+    // Jump till the 'x,y' position
+    const unsigned int dstWidthBytes = dstWidth * bytesPerPixel;
+    dstBuffer += ( y * dstWidthBytes + x * bytesPerPixel );
+
+    for (unsigned int j = 0u; j < srcHeight; ++j)
+    {
+      const unsigned int srcLineIndex = j * srcWidth;
+      for (unsigned int i = 0u; i < srcWidth; ++i)
+      {
+        const float srcAlpha = TO_FLOAT * static_cast<float>( *( srcBuffer + bytesPerPixel * ( srcLineIndex + i ) + alphaIndex ) );
+        const float dstAlpha = TO_FLOAT * static_cast<float>( *(dstBuffer + i*bytesPerPixel + alphaIndex) );
+
+        // Blends the alpha channel.
+        const float oneMinusSrcAlpha = 1.f - srcAlpha;
+        outputColor[alphaIndex] = 1.f - (oneMinusSrcAlpha * (1.f - dstAlpha));
+
+        // Blends the RGB channels.
+        const bool isOutputAlphaZero = outputColor[alphaIndex] < Dali::Math::MACHINE_EPSILON_1000;
+        if( isOutputAlphaZero )
+        {
+          std::fill( outputColor, outputColor + bytesPerPixel, 0.f );
+        }
+        else
+        {
+          const float srcAlphaOverOutputAlpha = srcAlpha / outputColor[alphaIndex];                                    // fgAlpha / alpha
+          const float dstAlphaOneMinusSrcAlphaOverOutputAlpha = dstAlpha * oneMinusSrcAlpha / outputColor[alphaIndex]; // bgAlpha * ( 1 - fgAlpha ) / alpha
+          for (unsigned int index = 0u; index < alphaIndex; ++index)
+          {
+            const float dstComponent = TO_FLOAT * static_cast<float>( *( dstBuffer + i * bytesPerPixel + index ) ) * dstAlpha;
+            const float srcComponent = TO_FLOAT * static_cast<float>(*(srcBuffer + bytesPerPixel * (srcLineIndex + i) + index) ) * srcAlpha;
+            outputColor[index] = ( srcComponent * srcAlphaOverOutputAlpha ) + ( dstComponent * dstAlphaOneMinusSrcAlphaOverOutputAlpha );
+          }
+        }
+
+        for (unsigned int index = 0u; index < bytesPerPixel; ++index)
+        {
+          *(dstBuffer + i * bytesPerPixel + index) = static_cast<unsigned char>( TO_UCHAR * outputColor[index] );
+        }
+      }
+
+      dstBuffer += dstWidthBytes;
+    }
+  }
+}
+
+} // namespace DevelText
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/devel-api/text/text-utils-devel.h b/dali-toolkit/devel-api/text/text-utils-devel.h
new file mode 100755 (executable)
index 0000000..83c6ea9
--- /dev/null
@@ -0,0 +1,201 @@
+#ifndef DALI_TOOLKIT_TEXT_UTILS_DEVEL_H
+#define DALI_TOOLKIT_TEXT_UTILS_DEVEL_H
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali-toolkit/public-api/dali-toolkit-common.h>
+#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
+#include <dali/devel-api/text-abstraction/text-abstraction-definitions.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace DevelText
+{
+
+/**
+ * @brief Struct with the text and style parameters to be rendered into a pixel buffer.
+ */
+struct DALI_TOOLKIT_API RendererParameters
+{
+  RendererParameters()
+  : text{},
+    horizontalAlignment{ "begin" },
+    verticalAlignment{ "top" },
+    fontFamily{},
+    fontWeight{},
+    fontWidth{},
+    fontSlant{},
+    layout{ "singleLine" },
+    circularAlignment{ "begin" },
+    textColor{ Color::WHITE },
+    fontSize{ 0.f },
+    textWidth{ 0u },
+    textHeight{ 0u },
+    radius{ 0u },
+    beginAngle{ 0.f },
+    incrementAngle{ 0.f },
+    ellipsisEnabled{ true },
+    markupEnabled{ false },
+    isTextColorSet{ false }
+  {}
+
+  std::string text;                ///< The text to be rendered encoded in utf8.
+
+  std::string horizontalAlignment; ///< The horizontal alignment: one of {"begin", "center", "end"}.
+  std::string verticalAlignment;   ///< The vertical alignment: one of {"top", "center", "bottom"}.
+
+  std::string fontFamily;          ///< The font's family.
+  std::string fontWeight;          ///< The font's weight: one of {"thin", "ultraLight", "extraLight", "light", "demiLight", "semiLight", "book", "normal", "regular", "medium", "demiBold", "semiBold", "bold", "ultraBold", "extraBold", "black", "heavy", "extraBlack"}.
+  std::string fontWidth;           ///< The font's width: one of {"ultraCondensed", "extraCondensed", "condensed", "semiCondensed", "normal", "semiExpanded", "expanded", "extraExpanded", "ultraExpanded"}.
+  std::string fontSlant;           ///< The font's slant. one of {"normal", "roman", "italic", "oblique"}
+  std::string layout;              ///< The type of layout: one of {"singleLine", "multiLine", "circular"}
+  std::string circularAlignment;   ///< The text alignment within the arc: one of {"begin", "center", "end"}. The @p horizontalAlignment and @p verticalAlignment can be used to align the text within the text area.
+
+  Vector4 textColor;               ///< The default text's color. Default is white.
+
+  float fontSize;           ///< The font's size (in points).
+
+  unsigned int textWidth;          ///< The width in pixels of the boundaries where the text is going to be laid-out.
+  unsigned int textHeight;         ///< The height in pixels of the boundaries where the text is going to be laid-out.
+
+  unsigned int radius;             ///< The radius in pixels of the circular text.
+  float beginAngle;                ///< The begin angle in degrees of the text area on the circle. The top of the circle is 0°, the right side 90°, the bottom 180° and the left 270°.
+  float incrementAngle;            ///< The increment angle in degrees of the text area on the circle. The @p incrementAngle defines a direction. If positive, the text will be laid out clockwise.
+
+  bool ellipsisEnabled:1;          ///< Whether the ellipsis layout option is enabled.
+  bool markupEnabled:1;            ///< Whether the mark-up processor is enabled.
+  bool isTextColorSet:1;           ///< Whether a default color has been set.
+};
+
+/**
+ * @brief Struct with info of the embedded items layout.
+ */
+struct DALI_TOOLKIT_API EmbeddedItemInfo
+{
+  TextAbstraction::CharacterIndex characterIndex;       ///< Index to the character within the string.
+  TextAbstraction::GlyphIndex glyphIndex;               ///< Index to the glyph
+  Vector2 position;                                     ///< The layout position within the buffer (top, left corner).
+  Size size;                                            ///< The size within the buffer of the embedded item.
+  Size rotatedSize;                                     ///< The rotated size within the buffer of the embedded item.
+  Degree angle;                                         ///< Rotation angle of the pixel buffer in degrees.
+  TextAbstraction::ColorBlendingMode colorBlendingMode; ///< Whether the color of the image is multiplied by the color of the text.
+};
+
+/**
+* @brief Struct with the parameters needed to build a shadow for the given pixel buffer.
+*/
+struct DALI_TOOLKIT_API ShadowParameters
+{
+  Devel::PixelBuffer input; ///< The input pixel buffer used to create the shadow.
+  Vector4 textColor;        ///< The color of the text.
+  Vector4 color;            ///< The color of the shadow.
+  Vector2 offset;           ///< The offset of the shadow.
+  bool blendShadow;         ///< Whether to blend the shadow.
+};
+
+/**
+ * @brief Renders text into a pixel buffer.
+ *
+ * @note: Can process a mark-up string.
+ * @note: It does the font selection, RTL reordering, shaping and layouting.
+ * @note: The width of the pixel buffer may be different to the given @e textWidth
+ *        due to some padding pixels added.
+ *
+ *  The text is laid-out for the given size @e (textWidth,textHeight).
+ *  If the @e multiLineEnabled option is enabled, the text will wrap in lines.
+ *  If the @e ellipsisEnabled option is enabled, the text will be ellided if
+ *  there is no more space for new lines.
+ *
+ *  It won't be rendered the parts of the text exceeding the boundaries of
+ *  the given width and height.
+ *
+ *  If the given @e textHeight is zero, a big enough pixel buffer will be created
+ *  to render the full text.
+ *
+ *  If the given @e textWidth is zero, the 'natural size' of the text will be
+ *  used to create the pixel buffer to render the full text.
+ *
+ *  If the radius is not zero, the text will be laid-out following a circular path.
+ *  In that case the text is laid-out in a single line.
+ *
+ * If the mark-up string contains embedded items, the @p embeddedItemLayout vector
+ * contains the layout info of each embedded item.
+ *
+ * @param[in] textParameters The text and style options.
+ * @param[out] embeddedItemLayout The layout info of the embedded items.
+ *
+ * @return A pixel buffer with the text rendered on it.
+ */
+DALI_TOOLKIT_API Devel::PixelBuffer Render( const RendererParameters& textParameters, Vector<EmbeddedItemInfo>& embeddedItemLayout );
+
+/**
+ * @brief Creates a shadow for the text given in the input pixel buffer.
+ *
+ * The function returns a RGBA8888 pixel buffer with the text and its shadow rendered on it.
+ *
+ * The pixel format of the @e input pixel buffer could be an A8 or an RGBA8888. If it's
+ * an A8 pixel buffer, it uses the given @e textColor to give color to the text. Otherwise
+ * it uses the color of the @e input pixel buffer.
+ *
+ * @param[in] shadowParameters The parameters needed to create the text's shadow.
+ *
+ * @return A pixel buffer with the text and the shadow rendered on it.
+ */
+DALI_TOOLKIT_API Devel::PixelBuffer CreateShadow(const ShadowParameters& shadowParameters);
+
+/**
+ * @brief Converts a @p pixelBuffer with pixel format A8 to RGBA8888 using the given @p color.
+ *
+ * @note Does nothing if the @p pixelBuffer is not A8.
+ *
+ * @param[in] pixelBuffer The pixel buffer with pixel format A8
+ * @param[in] color The color used to convert to RGBA8888
+ * @param[in] multiplyByAlpha Whether to multiply the @p color with the alpha value of the @p pixel @p buffer.
+ *
+ * @return The pixel buffer converted to RGBA8888.
+ */
+DALI_TOOLKIT_API Devel::PixelBuffer ConvertToRgba8888( Devel::PixelBuffer pixelBuffer, const Vector4& color, bool multiplyByAlpha );
+
+/**
+* @brief Updates the @p dst pixel buffer with the data from @p src pixel buffer.
+*
+* @note Both pixel buffers must have the same pixel format. Does nothing if both pixel format are different.
+* @note The function does nothing if the @p src pixel buffer doesn't fit into the @p dst pixel buffer.
+*
+* The @p src pixel buffer could be blended with the @p dst pixel buffer if @p blend is set to @e true.
+*
+* @param[in] src The pixel buffer from where the data is read.
+* @param[in] dst The pixel buffer where the data is written..
+* @param[in] x The top left corner's X within the destination pixel buffer.
+* @param[in] y The top left corner's y within the destination pixel buffer.
+* @param[in] blend Whether to blend the source pixel buffer with the destination pixel buffer as background.
+*/
+DALI_TOOLKIT_API void UpdateBuffer( Devel::PixelBuffer src, Devel::PixelBuffer dst, unsigned int x, unsigned int y, bool blend);
+
+} // namespace DevelText
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_UTILS_DEVEL_H
index 1f05bd7..92d4e8e 100644 (file)
@@ -37,9 +37,11 @@ namespace Action
  */
 enum Type
 {
-  PLAY,        ///< Play the animated vector image.
-  PAUSE,       ///< Pause the animated vector image.
-  STOP         ///< Stop the animated vector image. This is also Default playback mode.
+  PLAY,            ///< Play the animated vector image.
+  PAUSE,           ///< Pause the animated vector image.
+  STOP,            ///< Stop the animated vector image. This is also Default playback mode.
+  JUMP_TO,         ///< Jump to the specified frame. Property::FLOAT value should be passed.
+  UPDATE_PROPERTY  ///< Update the properties of the animated vector image.
 };
 
 } // namespace Action
index 2ae2726..d48eea8 100644 (file)
@@ -99,8 +99,14 @@ enum Type
    * @details Name "playState", type PlayState (Property::INTEGER)
    * @note This property is read-only.
    */
-  PLAY_STATE = ORIENTATION_CORRECTION + 5
+  PLAY_STATE = ORIENTATION_CORRECTION + 5,
 
+  /**
+   * @brief The animation progress the AnimatedVectorImageVisual will use.
+   * @details Name "currentProgress", Type Property::FLOAT, between [0, 1] or between the play range if specified
+   * @note This property is read-only.
+   */
+  CURRENT_PROGRESS = ORIENTATION_CORRECTION + 6
 };
 
 } //namespace Property
index 8880b31..aee1bc0 100644 (file)
@@ -1240,19 +1240,6 @@ bool AccessibilityManager::AccessibilityActionZoom()
   return ret;
 }
 
-bool AccessibilityManager::AccessibilityActionReadIndicatorInformation()
-{
-  Dali::Toolkit::AccessibilityManager handle( this );
-  if( !mActionReadIndicatorInformationSignal.Empty() )
-  {
-    mActionReadIndicatorInformationSignal.Emit( handle );
-  }
-
-  // TODO: Read the information in the indicator
-
-  return mIsAccessibilityTtsEnabled;
-}
-
 bool AccessibilityManager::AccessibilityActionReadPauseResume()
 {
   Dali::Toolkit::AccessibilityManager handle( this );
index 69e924a..f794170 100644 (file)
@@ -654,12 +654,6 @@ private:
   virtual bool AccessibilityActionZoom();
 
   /**
-   * Perform the accessibility action to read the information in the indicator (by two fingers triple tap).
-   * @return whether the accessibility action is performed or not.
-   */
-  virtual bool AccessibilityActionReadIndicatorInformation();
-
-  /**
    * Perform the accessibility action to pause/resume the current read out (by two fingers single tap).
    * @return whether the accessibility action is performed or not.
    */
index b3d867c..4375a29 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -307,7 +307,7 @@ void FeedbackStyle::LoadFromString( const string& data )
 
             if( signalFeedbackInfo.mHasHapticFeedbackInfo || signalFeedbackInfo.mHasSoundFeedbackInfo )
             {
-              AddSignalInfo( themeInfo, signalFeedbackInfo );
+              AddSignalInfo( themeInfo, std::move( signalFeedbackInfo ) );
             }
           }
         }
@@ -320,10 +320,10 @@ void FeedbackStyle::LoadFromString( const string& data )
 
 } // LoadFromString()
 
-void FeedbackStyle::AddSignalInfo( FeedbackStyleInfo& styleInfo, SignalFeedbackInfo signalInfo )
+void FeedbackStyle::AddSignalInfo( FeedbackStyleInfo& styleInfo, SignalFeedbackInfo&& signalInfo )
 {
   bool updated = false;
-  std::vector<SignalFeedbackInfo>::iterator iter;
+  SignalFeedbackInfoContainer::iterator iter;
 
   // If info exists for the signal then update it, else add new
   for( iter = styleInfo.mSignalFeedbackInfoList.begin(); iter != styleInfo.mSignalFeedbackInfoList.end(); ++iter )
@@ -344,7 +344,7 @@ void FeedbackStyle::AddSignalInfo( FeedbackStyleInfo& styleInfo, SignalFeedbackI
 
   if( !updated )
   {
-    styleInfo.mSignalFeedbackInfoList.push_back( signalInfo );
+    styleInfo.mSignalFeedbackInfoList.emplace_back( std::move( signalInfo ) );
   }
 }
 
index bf6ea3f..3693369 100644 (file)
@@ -2,7 +2,7 @@
 #define __DALI_INTERNAL_FEEDBACK_STYLE_H__
 
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -121,7 +121,7 @@ private:
    * @param [in] styleInfo The information will be stored here.
    * @param [in] signalInfo The information to add.
    */
-  void AddSignalInfo( FeedbackStyleInfo& styleInfo, SignalFeedbackInfo signalInfo );
+  void AddSignalInfo( FeedbackStyleInfo& styleInfo, SignalFeedbackInfo&& signalInfo );
 
   /**
    * Map a pattern string to feedback pattern ID.
index 3a0375e..be6c728 100755 (executable)
@@ -135,6 +135,7 @@ toolkit_src_files = \
    $(toolkit_src_dir)/text/logical-model-impl.cpp \
    $(toolkit_src_dir)/text/markup-processor.cpp \
    $(toolkit_src_dir)/text/markup-processor-color.cpp \
+   $(toolkit_src_dir)/text/markup-processor-embedded-item.cpp \
    $(toolkit_src_dir)/text/markup-processor-font.cpp \
    $(toolkit_src_dir)/text/markup-processor-helper-functions.cpp \
    $(toolkit_src_dir)/text/multi-language-support.cpp \
index 09224ee..b633523 100644 (file)
@@ -196,7 +196,7 @@ void Grid::OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpe
   DetermineNumberOfColumns( availableContentWidth );
 
   // Locations define the start, end,top and bottom of each cell.
-  mLocations->CalculateLocations( mNumColumns, availableContentWidth.AsInteger(), availableContentHeight.AsInteger(), childCount, 0, 0 );
+  mLocations->CalculateLocations( mNumColumns, availableContentWidth.AsInteger(), availableContentHeight.AsInteger(), childCount );
 
 
   SetMeasuredDimensions( ResolveSizeAndState( widthSize, widthMeasureSpec, MeasuredSize::State::MEASURED_SIZE_OK ),
index a4d3060..847bcc1 100644 (file)
@@ -55,9 +55,7 @@ GridLocations::~GridLocations(){}
 void GridLocations::CalculateLocations( int numberOfColumns,
                                         unsigned int availableWidth,
                                         unsigned int availableHeight,
-                                        unsigned int numberOfCells,
-                                        unsigned int columnWidth,
-                                        unsigned int rowHeight )
+                                        unsigned int numberOfCells )
 {
   DALI_ASSERT_DEBUG( numberOfColumns > 0 && "number of columns should be greater than 0" );
   numberOfColumns = std::max ( numberOfColumns, 1 );
@@ -70,30 +68,14 @@ void GridLocations::CalculateLocations( int numberOfColumns,
   // If number of cells not cleanly dividable by colums, add another row to house remainder cells.
   numberOfRows += (numberOfCells%numberOfColumns)?1:0;
 
-  unsigned int maxColumnWidth = availableWidth / numberOfColumns;
+  // Safe as numberOfColumns is guaranteed to be > 0
+  unsigned int columnWidth = availableWidth / numberOfColumns;
 
-  if( columnWidth > 0 )
-  {
-    // Column width supplied so use this unless exceeds available width.
-    columnWidth = std::min( columnWidth, maxColumnWidth );
-  }
-  else
-  {
-    // Column width not supplied so use calculated value
-    columnWidth = maxColumnWidth;
-  }
+  unsigned int rowHeight = availableHeight;
 
-  unsigned int maxRowHeight = availableHeight / numberOfRows;
-
-  if( rowHeight > 0 )
-  {
-    // Column height supplied so use this unless exceeds available height.
-    rowHeight = std::min( rowHeight, maxRowHeight );
-  }
-  else
+  if( numberOfRows > 0 )
   {
-    // Column height not supplied so use calculated value
-    rowHeight = maxRowHeight;
+    rowHeight = availableHeight / numberOfRows;
   }
 
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "ColumWidth[%d] RowHeight[%d] NumberOfRows[%d] NumberOfColumns[%d]\n",
@@ -154,4 +136,4 @@ GridLocations::LocationVector GridLocations::GetLocations()
 } // namespace Internal
 
 } // namespace Toolkit
-} // namespace Dali
\ No newline at end of file
+} // namespace Dali
index 2bc4359..afc1437 100644 (file)
@@ -73,8 +73,7 @@ public:
    * Uses the given parameters to calculate the x,y coordinates of each cell and cell size.
    */
   void CalculateLocations( int numberOfColumns, unsigned int availableWidth,
-                           unsigned int availableHeight, unsigned int numberOfCells,
-                           unsigned int columnWidth, unsigned int rowHeight );
+                           unsigned int availableHeight, unsigned int numberOfCells );
 
   LocationVector GetLocations();
 
@@ -95,4 +94,4 @@ private:
 } // namespace Toolkit
 } // namespace Dali
 
-#endif // DALI_TOOLKIT_INTERNAL_LAYOUTING_GRID_LOCATIONS_H
\ No newline at end of file
+#endif // DALI_TOOLKIT_INTERNAL_LAYOUTING_GRID_LOCATIONS_H
index 9d0b947..b0637b3 100644 (file)
@@ -347,13 +347,19 @@ void LayoutController::PerformLayoutPositioning( LayoutPositionDataArray& layout
     {
       if( !layoutPositionData.animated )
       {
-        actor.SetPosition( layoutPositionData.left, layoutPositionData.top );
-        actor.SetSize( layoutPositionData.right - layoutPositionData.left, layoutPositionData.bottom - layoutPositionData.top );
+        actor.SetX( layoutPositionData.left );
+        actor.SetY( layoutPositionData.top );
+
+        actor.SetProperty( Actor::Property::SIZE_WIDTH, layoutPositionData.right - layoutPositionData.left );
+        actor.SetProperty( Actor::Property::SIZE_HEIGHT, layoutPositionData.bottom - layoutPositionData.top );
       }
       else
       {
-        actor.SetPosition( actor.GetCurrentPosition() );
-        actor.SetSize( actor.GetCurrentSize() );
+        actor.SetX( actor.GetCurrentPosition().x );
+        actor.SetY( actor.GetCurrentPosition().y );
+
+        actor.SetProperty( Actor::Property::SIZE_WIDTH, actor.GetCurrentSize().x );
+        actor.SetProperty( Actor::Property::SIZE_HEIGHT, actor.GetCurrentSize().y );
       }
     }
   }
index 8f78c32..3606dd6 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_LAYOUT_CONTROLLER_H
 
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@
  */
 #include <list>
 #include <dali/public-api/object/base-object.h>
-#include <dali/integration-api/core.h>
+#include <dali/integration-api/processor-interface.h>
 #include <dali-toolkit/public-api/controls/control.h>
 #include <dali-toolkit/devel-api/layouting/layout-controller.h>
 #include <dali-toolkit/devel-api/layouting/layout-item-impl.h>
index 221ecbd..eb354c9 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_TOOLKIT_TEXT_CHARACTER_RUN_H__
-#define __DALI_TOOLKIT_TEXT_CHARACTER_RUN_H__
+#ifndef DALI_TOOLKIT_TEXT_CHARACTER_RUN_H
+#define DALI_TOOLKIT_TEXT_CHARACTER_RUN_H
 
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,6 +35,16 @@ namespace Text
  */
 struct CharacterRun
 {
+  CharacterRun()
+  : characterIndex{ 0u },
+    numberOfCharacters{ 0u }
+  {}
+
+  CharacterRun( CharacterIndex characterIndex, Length numberOfCharacters )
+  : characterIndex{ characterIndex },
+    numberOfCharacters{ numberOfCharacters }
+  {}
+
   CharacterIndex characterIndex;     ///< Index to the first character.
   Length         numberOfCharacters; ///< Number of characters in the run.
 };
@@ -45,4 +55,4 @@ struct CharacterRun
 
 } // namespace Dali
 
-#endif // __DALI_TOOLKIT_TEXT_CHARACTER_RUN_H__
+#endif // DALI_TOOLKIT_TEXT_CHARACTER_RUN_H
diff --git a/dali-toolkit/internal/text/embedded-item.h b/dali-toolkit/internal/text/embedded-item.h
new file mode 100755 (executable)
index 0000000..496c207
--- /dev/null
@@ -0,0 +1,60 @@
+#ifndef DALI_TOOLKIT_TEXT_EMBEDDED_ITEM_H
+#define DALI_TOOLKIT_TEXT_EMBEDDED_ITEM_H
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/text-definitions.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+/**
+ * @brief An embedded item within the text.
+ *
+ * The @e url of the image is optional. If there is no image
+ * the layout engine will use the @e width and @e height to
+ * create a space inside the text. This gap can be filled later.
+ *
+ * A color blending mode can be set. The default is NONE, the
+ * image will use its own color. If MULTIPLY is set, the color
+ * of the image will be multiplied by the color of the text.
+ */
+struct EmbeddedItem
+{
+  CharacterIndex    characterIndex;    ///< The character's index of the embedded item within the string.
+  char*             url;               ///< The url path of the image.
+  Length            urlLength;         ///< The length of the url.
+  unsigned int      width;             ///< The width of the item.
+  unsigned int      height;            ///< The height of the item.
+  ColorBlendingMode colorBlendingMode; ///< Whether the color of the image is multiplied by the color of the text.
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_EMBEDDED_ITEM_H
index ada640c..b14ab1d 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_TOOLKIT_TEXT_FONT_DESCRIPTION_RUN_H__
-#define __DALI_TOOLKIT_TEXT_FONT_DESCRIPTION_RUN_H__
+#ifndef DALI_TOOLKIT_TEXT_FONT_DESCRIPTION_RUN_H
+#define DALI_TOOLKIT_TEXT_FONT_DESCRIPTION_RUN_H
 
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -39,6 +39,50 @@ namespace Text
  */
 struct FontDescriptionRun
 {
+  /**
+   * Default constructor to set the default values of bitfields
+   */
+  FontDescriptionRun()
+  : characterRun{},
+    familyName{ nullptr },
+    familyLength{ 0u },
+    weight{ FontWeight::NONE },
+    width{ FontWidth::NONE },
+    slant{ FontSlant::NONE },
+    size{ 0u },
+    familyDefined{ false },
+    weightDefined{ false },
+    widthDefined{ false },
+    slantDefined{ false },
+    sizeDefined{ false }
+  {}
+
+  FontDescriptionRun( const CharacterRun& characterRun,
+                      char* familyName,
+                      Length familyLength,
+                      FontWeight weight,
+                      FontWidth width,
+                      FontSlant slant,
+                      PointSize26Dot6 size,
+                      bool familyDefined,
+                      bool weightDefined,
+                      bool widthDefined,
+                      bool slantDefined,
+                      bool sizeDefined )
+  : characterRun{ characterRun },
+    familyName{ familyName },
+    familyLength{ familyLength },
+    weight{ weight },
+    width{ width },
+    slant{ slant },
+    size{ size },
+    familyDefined{ familyDefined },
+    weightDefined{ weightDefined },
+    widthDefined{ widthDefined },
+    slantDefined{ slantDefined },
+    sizeDefined{ sizeDefined }
+  {}
+
   CharacterRun    characterRun; ///< The initial character index and the number of characters of the run.
   char*           familyName;   ///< The font's family name.
   Length          familyLength; ///< The length of the font's family name.
@@ -47,11 +91,11 @@ struct FontDescriptionRun
   FontSlant       slant;        ///< The font's slant.
   PointSize26Dot6 size;         ///< The font's size.
 
-  bool familyDefined : 1; ///< Whether the font's family is defined.
-  bool weightDefined : 1; ///< Whether the font's weight is defined.
-  bool widthDefined  : 1; ///< Whether the font's width is defined.
-  bool slantDefined  : 1; ///< Whether the font's slant is defined.
-  bool sizeDefined   : 1; ///< Whether the font's size is defined.
+  bool familyDefined : 1;       ///< Whether the font's family is defined.
+  bool weightDefined : 1;       ///< Whether the font's weight is defined.
+  bool widthDefined  : 1;       ///< Whether the font's width is defined.
+  bool slantDefined  : 1;       ///< Whether the font's slant is defined.
+  bool sizeDefined   : 1;       ///< Whether the font's size is defined.
 };
 
 } // namespace Text
@@ -60,4 +104,4 @@ struct FontDescriptionRun
 
 } // namespace Dali
 
-#endif // __DALI_TOOLKIT_TEXT_FONT_DESCRIPTION_RUN_H__
+#endif // DALI_TOOLKIT_TEXT_FONT_DESCRIPTION_RUN_H
index a787558..8190fcd 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_TOOLKIT_TEXT_FONT_RUN_H__
-#define __DALI_TOOLKIT_TEXT_FONT_RUN_H__
+#ifndef DALI_TOOLKIT_TEXT_FONT_RUN_H
+#define DALI_TOOLKIT_TEXT_FONT_RUN_H
 
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,9 +18,6 @@
  *
  */
 
-// EXTERNAL INCLUDES
-#include <dali/devel-api/text-abstraction/font-list.h>
-
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/character-run.h>
 
@@ -38,10 +35,10 @@ namespace Text
  */
 struct FontRun
 {
-  CharacterRun characterRun;      ///< The initial character index and the number of characters of the run.
-  FontId       fontId;            ///< Font id of the run.
-  bool         softwareItalic:1;    ///< Whether font needs software support to draw italic style
-  bool         softwareBold:1;      ///< Whether font needs software support to draw bold style
+  CharacterRun characterRun;       ///< The initial character index and the number of characters of the run.
+  FontId       fontId;             ///< Font id of the run.
+  bool         isItalicRequired:1; ///< Whether the italic style is required.
+  bool         isBoldRequired:1;   ///< Whether the bold style is required.
 };
 
 } // namespace Text
@@ -50,4 +47,4 @@ struct FontRun
 
 } // namespace Dali
 
-#endif // __DALI_TOOLKIT_TEXT_FONT_RUN_H__
+#endif // DALI_TOOLKIT_TEXT_FONT_RUN_H
old mode 100644 (file)
new mode 100755 (executable)
index 9c7c8ec..ef9098c
@@ -58,21 +58,41 @@ void GetGlyphsMetrics( GlyphIndex glyphIndex,
   const GlyphInfo& firstGlyph = *( glyphsBuffer + glyphIndex );
 
   Text::FontMetrics fontMetrics;
-  metrics->GetFontMetrics( firstGlyph.fontId, fontMetrics );
+  if( 0u != firstGlyph.fontId )
+  {
+    metrics->GetFontMetrics( firstGlyph.fontId, fontMetrics );
+  }
+  else if( 0u != firstGlyph.index )
+  {
+    // It may be an embedded image.
+    fontMetrics.ascender = firstGlyph.height;
+    fontMetrics.descender = 0.f;
+    fontMetrics.height = fontMetrics.ascender;
+  }
+
+  const bool isItalicFont = metrics->HasItalicStyle( firstGlyph.fontId );
 
   glyphMetrics.fontId = firstGlyph.fontId;
   glyphMetrics.fontHeight = fontMetrics.height;
-  glyphMetrics.width = firstGlyph.width;
+  glyphMetrics.width = firstGlyph.width + ( ( firstGlyph.isItalicRequired && !isItalicFont ) ? static_cast<unsigned int>( TextAbstraction::FontClient::DEFAULT_ITALIC_ANGLE * static_cast<float>( firstGlyph.height ) ) : 0u );
   glyphMetrics.advance = firstGlyph.advance;
   glyphMetrics.ascender = fontMetrics.ascender;
   glyphMetrics.xBearing = firstGlyph.xBearing;
 
-  for( unsigned int i = 1u; i < numberOfGlyphs; ++i )
+  if( 1u < numberOfGlyphs )
   {
-    const GlyphInfo& glyphInfo = *( glyphsBuffer + glyphIndex + i );
+    const float widthInit = firstGlyph.xBearing;
+
+    for( unsigned int i = 1u; i < numberOfGlyphs; ++i )
+    {
+      const GlyphInfo& glyphInfo = *( glyphsBuffer + glyphIndex + i );
+
+      glyphMetrics.width = glyphMetrics.advance + glyphInfo.xBearing + glyphInfo.width + ( ( firstGlyph.isItalicRequired && !isItalicFont ) ? static_cast<unsigned int>( TextAbstraction::FontClient::DEFAULT_ITALIC_ANGLE * static_cast<float>( firstGlyph.height ) ) : 0u );
+      glyphMetrics.advance += glyphInfo.advance;
+
+    }
 
-    glyphMetrics.advance += glyphInfo.advance;
-    glyphMetrics.width += glyphInfo.width;
+    glyphMetrics.width -= widthInit;
   }
 }
 
index f97a8ea..5594c01 100755 (executable)
@@ -117,26 +117,31 @@ struct Engine::Impl
   /**
    * @brief Updates the line ascender and descender with the metrics of a new font.
    *
-   * @param[in] fontId The id of the new font.
+   * @param[in] glyphMetrics The metrics of the new font.
    * @param[in,out] lineLayout The line layout.
    */
-  void UpdateLineHeight( FontId fontId, LineLayout& lineLayout )
+  void UpdateLineHeight( const GlyphMetrics& glyphMetrics, LineLayout& lineLayout )
   {
     Text::FontMetrics fontMetrics;
-    mMetrics->GetFontMetrics( fontId, fontMetrics );
-
-    // Sets the maximum ascender.
-    if( fontMetrics.ascender > lineLayout.ascender )
+    if( 0u != glyphMetrics.fontId )
     {
-      lineLayout.ascender = fontMetrics.ascender;
+      mMetrics->GetFontMetrics( glyphMetrics.fontId, fontMetrics );
     }
-
-    // Sets the minimum descender.
-    if( fontMetrics.descender < lineLayout.descender )
+    else
     {
-      lineLayout.descender = fontMetrics.descender;
+      fontMetrics.ascender = glyphMetrics.fontHeight;
+      fontMetrics.descender = 0.f;
+      fontMetrics.height = fontMetrics.ascender;
+      fontMetrics.underlinePosition = 0.f;
+      fontMetrics.underlineThickness = 1.f;
     }
 
+    // Sets the maximum ascender.
+    lineLayout.ascender = std::max( lineLayout.ascender, fontMetrics.ascender );
+
+    // Sets the minimum descender.
+    lineLayout.descender = std::min( lineLayout.descender, fontMetrics.descender );
+
     // set the line spacing
     lineLayout.lineSpacing = mDefaultLineSpacing;
   }
@@ -158,22 +163,18 @@ struct Engine::Impl
     {
       lineLayout.length += lineLayout.wsLengthEndOfLine;
 
-      lineLayout.wsLengthEndOfLine = tmpLineLayout.wsLengthEndOfLine;
+    lineLayout.wsLengthEndOfLine = tmpLineLayout.wsLengthEndOfLine;
     }
     else
     {
       lineLayout.wsLengthEndOfLine += tmpLineLayout.wsLengthEndOfLine;
     }
 
-    if( tmpLineLayout.ascender > lineLayout.ascender )
-    {
-      lineLayout.ascender = tmpLineLayout.ascender;
-    }
+    // Sets the maximum ascender.
+    lineLayout.ascender = std::max( lineLayout.ascender, tmpLineLayout.ascender );
 
-    if( tmpLineLayout.descender < lineLayout.descender )
-    {
-      lineLayout.descender = tmpLineLayout.descender;
-    }
+    // Sets the minimum descender.
+    lineLayout.descender = std::min( lineLayout.descender, tmpLineLayout.descender );
   }
 
   /**
@@ -239,7 +240,7 @@ struct Engine::Impl
 
     // Calculate the line height if there is no characters.
     FontId lastFontId = glyphMetrics.fontId;
-    UpdateLineHeight( lastFontId, tmpLineLayout );
+    UpdateLineHeight( glyphMetrics, tmpLineLayout );
 
     bool oneWordLaidOut = false;
 
@@ -266,7 +267,7 @@ struct Engine::Impl
       // If it's different the ascender and descender need to be updated.
       if( lastFontId != glyphMetrics.fontId )
       {
-        UpdateLineHeight( glyphMetrics.fontId, tmpLineLayout );
+        UpdateLineHeight( glyphMetrics, tmpLineLayout );
         lastFontId = glyphMetrics.fontId;
       }
 
@@ -572,7 +573,7 @@ struct Engine::Impl
     const bool ellipsis = isAutoScrollEnabled ? ( penY - layout.descender > layoutParameters.boundingBox.height ) :
                                                 ( ( penY - layout.descender > layoutParameters.boundingBox.height ) ||
                                                   ( ( mLayout == SINGLE_LINE_BOX ) &&
-                                                  ( layout.extraBearing + layout.length + layout.extraWidth > layoutParameters.boundingBox.width ) ) );
+                                                    ( layout.length > layoutParameters.boundingBox.width ) ) );
 
     if( ellipsis )
     {
@@ -613,7 +614,7 @@ struct Engine::Impl
       lineRun->characterRun.characterIndex = ellipsisLayout.characterIndex;
       lineRun->characterRun.numberOfCharacters = ellipsisLayout.numberOfCharacters;
       lineRun->width = ellipsisLayout.length;
-      lineRun->extraLength =  ( ellipsisLayout.wsLengthEndOfLine > 0.f ) ? ellipsisLayout.wsLengthEndOfLine - ellipsisLayout.extraWidth : 0.f;
+      lineRun->extraLength =  std::ceil( ( ellipsisLayout.wsLengthEndOfLine > 0.f ) ? ellipsisLayout.wsLengthEndOfLine - ellipsisLayout.extraWidth : 0.f );
       lineRun->ascender = ellipsisLayout.ascender;
       lineRun->descender = ellipsisLayout.descender;
       lineRun->direction = !RTL;
@@ -679,8 +680,12 @@ struct Engine::Impl
     else
     {
       lineRun.width = layout.extraBearing + layout.length + layout.extraWidth;
-      lineRun.extraLength = ( layout.wsLengthEndOfLine > 0.f ) ? layout.wsLengthEndOfLine - layout.extraWidth : 0.f;
+      lineRun.extraLength = std::ceil( ( layout.wsLengthEndOfLine > 0.f ) ? layout.wsLengthEndOfLine - layout.extraWidth : 0.f );
     }
+
+    // Rounds upward to avoid a non integer size.
+    lineRun.width = std::ceil( lineRun.width );
+
     lineRun.ascender = layout.ascender;
     lineRun.descender = layout.descender;
     lineRun.direction = !RTL;
@@ -716,7 +721,10 @@ struct Engine::Impl
     const GlyphInfo& glyphInfo = *( layoutParameters.glyphsBuffer + layoutParameters.totalNumberOfGlyphs - 1u );
 
     Text::FontMetrics fontMetrics;
-    mMetrics->GetFontMetrics( glyphInfo.fontId, fontMetrics );
+    if( 0u != glyphInfo.fontId )
+    {
+      mMetrics->GetFontMetrics( glyphInfo.fontId, fontMetrics );
+    }
 
     LineRun& lineRun = *( linesBuffer + numberOfLines );
     ++numberOfLines;
@@ -832,6 +840,9 @@ struct Engine::Impl
       UpdateLayoutSize( lines,
                         layoutSize );
 
+      // Rounds upward to avoid a non integer size.
+      layoutSize.height = std::ceil( layoutSize.height );
+
       // Nothing else do if there are no glyphs to layout.
       return false;
     }
@@ -910,6 +921,10 @@ struct Engine::Impl
         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--LayoutText width too small!\n\n" );
 
         lines.Resize( numberOfLines );
+
+        // Rounds upward to avoid a non integer size.
+        layoutSize.height = std::ceil( layoutSize.height );
+
         return false;
       }
 
@@ -1041,6 +1056,9 @@ struct Engine::Impl
       lines.Resize( numberOfLines );
     }
 
+    // Rounds upward to avoid a non integer size.
+    layoutSize.height = std::ceil( layoutSize.height );
+
     DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--LayoutText\n\n" );
 
     return true;
old mode 100644 (file)
new mode 100755 (executable)
index 9b66925..66c6d89
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -38,12 +38,26 @@ void FreeFontFamilyNames( Vector<FontDescriptionRun>& fontDescriptionRuns )
        it != endIt;
        ++it )
   {
-    delete (*it).familyName;
+    delete[] (*it).familyName;
   }
 
   fontDescriptionRuns.Clear();
 }
 
+void FreeEmbeddedItems( Vector<EmbeddedItem>& embeddedItem )
+{
+  for( Vector<EmbeddedItem>::Iterator it = embeddedItem.Begin(),
+         endIt = embeddedItem.End();
+       it != endIt;
+       ++it )
+  {
+    EmbeddedItem& item = *it;
+    delete[] item.url;
+  }
+
+  embeddedItem.Clear();
+}
+
 LogicalModelPtr LogicalModel::New()
 {
   return LogicalModelPtr( new LogicalModel() );
@@ -550,9 +564,15 @@ void LogicalModel::FindParagraphs( CharacterIndex index,
   }
 }
 
+void LogicalModel::ClearEmbeddedImages()
+{
+  FreeEmbeddedItems( mEmbeddedItems );
+}
+
 LogicalModel::~LogicalModel()
 {
   ClearFontDescriptionRuns();
+  ClearEmbeddedImages();
 }
 
 LogicalModel::LogicalModel()
old mode 100644 (file)
new mode 100755 (executable)
index 9f2fa31..b2fc5a1
@@ -1,8 +1,8 @@
-#ifndef __DALI_TOOLKIT_TEXT_LOGICAL_MODEL_IMPL_H__
-#define __DALI_TOOLKIT_TEXT_LOGICAL_MODEL_IMPL_H__
+#ifndef DALI_TOOLKIT_TEXT_LOGICAL_MODEL_IMPL_H
+#define DALI_TOOLKIT_TEXT_LOGICAL_MODEL_IMPL_H
 
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -27,6 +27,7 @@
 #include <dali-toolkit/internal/text/bidirectional-line-info-run.h>
 #include <dali-toolkit/internal/text/bidirectional-paragraph-info-run.h>
 #include <dali-toolkit/internal/text/color-run.h>
+#include <dali-toolkit/internal/text/embedded-item.h>
 #include <dali-toolkit/internal/text/font-run.h>
 #include <dali-toolkit/internal/text/font-description-run.h>
 #include <dali-toolkit/internal/text/paragraph-run.h>
@@ -177,6 +178,13 @@ public:
                        Length numberOfCharacters,
                        Vector<ParagraphRunIndex>& paragraphs );
 
+  // Embedded images
+
+  /**
+   * @brief Clears the embedded images.
+   */
+  void ClearEmbeddedImages();
+
 protected:
 
   /**
@@ -210,6 +218,7 @@ public:
   Vector<BidirectionalParagraphInfoRun> mBidirectionalParagraphInfo;
   Vector<CharacterDirection>            mCharacterDirections;              ///< For each character, whether is right to left. ( @e flase is left to right, @e true right to left ).
   Vector<BidirectionalLineInfoRun>      mBidirectionalLineInfo;
+  Vector<EmbeddedItem>                  mEmbeddedItems;
 
   BidirectionalLineRunIndex             mBidirectionalLineIndex;           ///< The last fetched bidirectional line info.
 };
@@ -220,4 +229,4 @@ public:
 
 } // namespace Dali
 
-#endif // __DALI_TOOLKIT_TEXT_LOGICAL_MODEL_IMPL_H__
+#endif // DALI_TOOLKIT_TEXT_LOGICAL_MODEL_IMPL_H
diff --git a/dali-toolkit/internal/text/markup-processor-embedded-item.cpp b/dali-toolkit/internal/text/markup-processor-embedded-item.cpp
new file mode 100755 (executable)
index 0000000..7751c01
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// FILE HEADER
+#include <dali-toolkit/internal/text/markup-processor-embedded-item.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/dali-vector.h>
+#include <memory.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/embedded-item.h>
+#include <dali-toolkit/internal/text/markup-processor-helper-functions.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+namespace
+{
+const std::string XHTML_URL_ATTRIBUTE("url");
+const std::string XHTML_WIDTH_ATTRIBUTE("width");
+const std::string XHTML_HEIGHT_ATTRIBUTE("height");
+const std::string XHTML_COLOR_BLENDING_ATTRIBUTE("color-blending");
+
+const std::string NONE("none");
+const std::string MULTIPLY("multiply");
+}
+
+void ProcessEmbeddedItem( const Tag& tag, EmbeddedItem& embeddedItem )
+{
+  embeddedItem.url = nullptr;
+  embeddedItem.urlLength = 0u;
+  embeddedItem.width = 0u;
+  embeddedItem.height = 0u;
+  embeddedItem.colorBlendingMode = ColorBlendingMode::NONE;
+
+  for( Vector<Attribute>::ConstIterator it = tag.attributes.Begin(),
+         endIt = tag.attributes.End();
+       it != endIt;
+       ++it )
+  {
+    const Attribute& attribute( *it );
+    if( TokenComparison(XHTML_URL_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength ) )
+    {
+      embeddedItem.urlLength = attribute.valueLength;
+      embeddedItem.url = new char[embeddedItem.urlLength];
+      memcpy(embeddedItem.url, attribute.valueBuffer, embeddedItem.urlLength);
+      // The memory is freed when the font run is removed from the logical model.
+    }
+    else if (TokenComparison(XHTML_WIDTH_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength))
+    {
+      embeddedItem.width = StringToUint(attribute.valueBuffer);
+    }
+    else if (TokenComparison(XHTML_HEIGHT_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength))
+    {
+      embeddedItem.height = StringToUint(attribute.valueBuffer);
+    }
+    else if (TokenComparison(XHTML_COLOR_BLENDING_ATTRIBUTE, attribute.nameBuffer, attribute.nameLength))
+    {
+      if (TokenComparison(MULTIPLY, attribute.valueBuffer, attribute.valueLength))
+      {
+        embeddedItem.colorBlendingMode = ColorBlendingMode::MULTIPLY;
+      }
+    }
+  }
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/text/markup-processor-embedded-item.h b/dali-toolkit/internal/text/markup-processor-embedded-item.h
new file mode 100755 (executable)
index 0000000..6333c35
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_EMBEDDED_ITEM_H
+#define DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_EMBEDDED_ITEM_H
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+struct Tag;
+struct EmbeddedItem;
+
+/**
+ * @brief Retrieves the @e embedded @e item from the @p tag.
+ *
+ * @param[in] tag The embedded item tag and its attributes.
+ * @param[in,out] embeddedItem The embedded item.
+ */
+void ProcessEmbeddedItem( const Tag& tag, EmbeddedItem& embeddedItem );
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_EMBEDDED_ITEM_H
old mode 100644 (file)
new mode 100755 (executable)
index 76d9a6a..6c133ae
@@ -92,6 +92,11 @@ void JumpToWhiteSpace( const char*& stringBuffer,
   for( ; ( WHITE_SPACE != *stringBuffer ) && ( stringBuffer < stringEndBuffer ); ++stringBuffer );
 }
 
+unsigned int StringToUint( const char* const uintStr )
+{
+  return static_cast<unsigned int>( strtoul( uintStr, NULL, 10 ) );
+}
+
 unsigned int StringToHex( const char* const uintStr )
 {
   return static_cast<unsigned int>( strtoul( uintStr, NULL, 16 ) );
old mode 100644 (file)
new mode 100755 (executable)
index d1ecbc8..2b0cafb
@@ -95,6 +95,15 @@ void JumpToWhiteSpace( const char*& stringBuffer,
                        const char* const stringEndBuffer );
 
 /**
+* @brief Converts a string into an unsigned int.
+*
+* @param[in] uintStr An unsigned int packed inside a string.
+*
+* @return The unsigned int value.
+*/
+unsigned int StringToUint( const char* const uintStr );
+
+/**
  * @brief Converts a string into an hexadecimal unsigned int.
  *
  * @param[in] uintStr An hexadecimal unsigned int packed inside a string.
index 25b4616..4565b9d 100755 (executable)
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/character-set-conversion.h>
 #include <dali-toolkit/internal/text/markup-processor-color.h>
+#include <dali-toolkit/internal/text/markup-processor-embedded-item.h>
 #include <dali-toolkit/internal/text/markup-processor-font.h>
 #include <dali-toolkit/internal/text/markup-processor-helper-functions.h>
 #include <dali-toolkit/internal/text/xhtml-entities.h>
 
-
-
 namespace Dali
 {
 
@@ -53,6 +52,7 @@ const std::string XHTML_U_TAG("u");
 const std::string XHTML_SHADOW_TAG("shadow");
 const std::string XHTML_GLOW_TAG("glow");
 const std::string XHTML_OUTLINE_TAG("outline");
+const std::string XHTML_ITEM_TAG("item");
 
 const char LESS_THAN      = '<';
 const char GREATER_THAN   = '>';
@@ -66,7 +66,7 @@ const char SEMI_COLON     = ';';
 const char CHAR_ARRAY_END = '\0';
 const char HEX_CODE       = 'x';
 
-const char WHITE_SPACE    = 0x20; // ASCII value of the white space.
+const char WHITE_SPACE    = 0x20;        // ASCII value of the white space.
 
 // Range 1 0x0u < XHTML_DECIMAL_ENTITY_RANGE <= 0xD7FFu
 // Range 2 0xE000u < XHTML_DECIMAL_ENTITY_RANGE <= 0xFFFDu
@@ -310,12 +310,15 @@ bool IsTag( const char*& markupStringBuffer,
   bool isQuotationOpen = false;
   bool attributesFound = false;
   tag.isEndTag = false;
+  bool isPreviousLessThan = false;
+  bool isPreviousSlash = false;
 
   const char character = *markupStringBuffer;
   if( LESS_THAN == character ) // '<'
   {
     tag.buffer = NULL;
     tag.length = 0u;
+    isPreviousLessThan = true;
 
     // if the iterator is pointing to a '<' character, then check if it's a mark-up tag is needed.
     ++markupStringBuffer;
@@ -327,12 +330,20 @@ bool IsTag( const char*& markupStringBuffer,
       {
         const char character = *markupStringBuffer;
 
-        if( SLASH == character ) // '/'
+        if( !isQuotationOpen && ( SLASH == character ) ) // '/'
         {
-          // if the tag has a '/' then it's an end or empty tag.
-          tag.isEndTag = true;
+          if (isPreviousLessThan)
+          {
+            tag.isEndTag = true;
+          }
+          else
+          {
+            // if the tag has a '/' it may be an end tag.
+            isPreviousSlash = true;
+          }
 
-          if( ( markupStringBuffer + 1u < markupStringEndBuffer ) && ( WHITE_SPACE >= *( markupStringBuffer + 1u ) ) && ( !isQuotationOpen ) )
+          isPreviousLessThan = false;
+          if( ( markupStringBuffer + 1u < markupStringEndBuffer ) && ( WHITE_SPACE >= *( markupStringBuffer + 1u ) ) )
           {
             ++markupStringBuffer;
             SkipWhiteSpace( markupStringBuffer, markupStringEndBuffer );
@@ -342,11 +353,21 @@ bool IsTag( const char*& markupStringBuffer,
         else if( GREATER_THAN == character ) // '>'
         {
           isTag = true;
+          if (isPreviousSlash)
+          {
+            tag.isEndTag = true;
+          }
+
+          isPreviousSlash = false;
+          isPreviousLessThan = false;
         }
         else if( QUOTATION_MARK == character )
         {
           isQuotationOpen = !isQuotationOpen;
           ++tag.length;
+
+          isPreviousSlash = false;
+          isPreviousLessThan = false;
         }
         else if( WHITE_SPACE >= character ) // ' '
         {
@@ -366,6 +387,9 @@ bool IsTag( const char*& markupStringBuffer,
 
           // If it's not any of the 'special' characters then just add it to the tag string.
           ++tag.length;
+
+          isPreviousSlash = false;
+          isPreviousLessThan = false;
         }
       }
     }
@@ -466,6 +490,8 @@ bool XHTMLNumericEntityToUtf8 ( const char* markupText, char* utf8 )
 
 void ProcessMarkupString( const std::string& markupString, MarkupProcessData& markupProcessData )
 {
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "markupString: %s\n", markupString.c_str() );
+
   // Reserve space for the plain text.
   const Length markupStringSize = markupString.size();
   markupProcessData.markupProcessedText.reserve( markupStringSize );
@@ -489,6 +515,7 @@ void ProcessMarkupString( const std::string& markupString, MarkupProcessData& ma
   CharacterIndex characterIndex = 0u;
   for( ; markupStringBuffer < markupStringEndBuffer; )
   {
+    tag.attributes.Clear();
     if( IsTag( markupStringBuffer,
                markupStringEndBuffer,
                tag ) )
@@ -654,6 +681,22 @@ void ProcessMarkupString( const std::string& markupString, MarkupProcessData& ma
           // Pop the top of the stack and set the number of characters of the run.
         }
       } // <outline></outline>
+      else if (TokenComparison(XHTML_ITEM_TAG, tag.buffer, tag.length))
+      {
+        if (tag.isEndTag)
+        {
+          // Create an embedded item instance.
+          EmbeddedItem item;
+          item.characterIndex = characterIndex;
+          ProcessEmbeddedItem(tag, item);
+
+          markupProcessData.items.PushBack(item);
+
+          // Insert white space character that will be replaced by the item.
+          markupProcessData.markupProcessedText.append( 1u, WHITE_SPACE );
+          ++characterIndex;
+        }
+      }
     }  // end if( IsTag() )
     else if( markupStringBuffer < markupStringEndBuffer )
     {
@@ -753,6 +796,14 @@ void ProcessMarkupString( const std::string& markupString, MarkupProcessData& ma
   else
   {
     markupProcessData.colorRuns.Resize( colorRunIndex );
+
+#ifdef DEBUG_ENABLED
+    for( unsigned int i=0; i<colorRunIndex; ++i )
+    {
+      ColorRun& run = markupProcessData.colorRuns[i];
+      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "run[%d] index: %d, length: %d, color %f,%f,%f,%f\n", i, run.characterRun.characterIndex, run.characterRun.numberOfCharacters, run.color.r, run.color.g, run.color.b, run.color.a );
+    }
+#endif
   }
 }
 
old mode 100644 (file)
new mode 100755 (executable)
index 0c43300..de66e7f
@@ -1,8 +1,8 @@
-#ifndef __DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_H__
-#define __DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_H__
+#ifndef DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_H
+#define DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_H
 
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/color-run.h>
+#include <dali-toolkit/internal/text/embedded-item.h>
 #include <dali-toolkit/internal/text/font-description-run.h>
 
 namespace Dali
@@ -41,15 +42,17 @@ namespace Text
 struct MarkupProcessData
 {
 MarkupProcessData( Vector<ColorRun>& colorRuns,
-                   Vector<FontDescriptionRun>& fontRuns )
+                   Vector<FontDescriptionRun>& fontRuns,
+                   Vector<EmbeddedItem>& items )
   : colorRuns( colorRuns ),
     fontRuns( fontRuns ),
+    items(items),
     markupProcessedText()
   {}
 
   Vector<ColorRun>&           colorRuns;           ///< The color runs.
   Vector<FontDescriptionRun>& fontRuns;            ///< The font description runs.
-
+  Vector<EmbeddedItem>&       items;               ///< The embedded items.
   std::string                 markupProcessedText; ///< The mark-up string.
 };
 
@@ -67,4 +70,4 @@ void ProcessMarkupString( const std::string& markupString, MarkupProcessData& ma
 
 } // namespace Dali
 
-#endif // __DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_H__
+#endif // DALI_TOOLKIT_TEXT_MARKUP_PROCESSOR_H
old mode 100644 (file)
new mode 100755 (executable)
index ad4ed41..868dba3
@@ -87,6 +87,18 @@ public:
     return mFontClient.GetGlyphMetrics( array, size, mGlyphType, true ); // inline for performance
   }
 
+  /**
+   * @brief Whether the font has Italic style.
+   *
+   * @param[in] fontId The font identifier.
+   *
+   * @return true if the font has italic style.
+   */
+  bool HasItalicStyle( FontId fontId ) const
+  {
+    return mFontClient.HasItalicStyle( fontId );
+  }
+
 protected:
 
   /**
index 607d159..81d815c 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -435,6 +435,8 @@ void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
   currentFontRun.characterRun.characterIndex = startIndex;
   currentFontRun.characterRun.numberOfCharacters = 0u;
   currentFontRun.fontId = 0u;
+  currentFontRun.isBoldRequired = false;
+  currentFontRun.isItalicRequired = false;
 
   // Get the font client.
   TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
@@ -448,16 +450,13 @@ void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
 
   bool isPreviousEmojiScript = false;
 
-  // Description of fallback font which is selected at current iteration.
-  TextAbstraction::FontDescription selectedFontDescription;
-
   CharacterIndex lastCharacter = startIndex + numberOfCharacters;
   for( Length index = startIndex; index < lastCharacter; ++index )
   {
     // Get the current character.
     const Character character = *( textBuffer + index );
-    bool needSoftwareBoldening = false;
-    bool needSoftwareItalic = false;
+    bool isItalicRequired = false;
+    bool isBoldRequired = false;
 
     // new description for current character
     TextAbstraction::FontDescription currentFontDescription;
@@ -536,6 +535,8 @@ void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
       currentFontRun.characterRun.characterIndex = currentFontRun.characterRun.characterIndex + currentFontRun.characterRun.numberOfCharacters;
       currentFontRun.characterRun.numberOfCharacters = 0u;
       currentFontRun.fontId = fontId;
+      currentFontRun.isItalicRequired = false;
+      currentFontRun.isBoldRequired = false;
     }
 
     // If the given font is not valid, it means either:
@@ -676,22 +677,17 @@ void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
     }
 #endif
 
-    if( fontId != currentFontRun.fontId )
-    {
-      fontClient.GetDescription(fontId,selectedFontDescription);
-    }
-
-    // Developer sets bold to character but selected font cannot support it
-    needSoftwareBoldening = ( currentFontDescription.weight >= TextAbstraction::FontWeight::BOLD ) && ( selectedFontDescription.weight < TextAbstraction::FontWeight::BOLD );
+    // Whether bols style is required.
+    isBoldRequired = ( currentFontDescription.weight >= TextAbstraction::FontWeight::BOLD );
 
-    // Developer sets italic to character but selected font cannot support it
-    needSoftwareItalic = ( currentFontDescription.slant == TextAbstraction::FontSlant::ITALIC ) && ( selectedFontDescription.slant < TextAbstraction::FontSlant::ITALIC );
+    // Whether italic style is required.
+    isItalicRequired = ( currentFontDescription.slant >= TextAbstraction::FontSlant::ITALIC );
 
     // The font is now validated.
     if( ( fontId != currentFontRun.fontId ) ||
         isNewParagraphCharacter ||
         // If font id is same as previous but style is diffrent, initialize new one
-        ( ( fontId == currentFontRun.fontId ) && ( ( needSoftwareBoldening != currentFontRun.softwareBold ) || ( needSoftwareItalic != currentFontRun.softwareItalic ) ) ) )
+        ( ( fontId == currentFontRun.fontId ) && ( ( isBoldRequired != currentFontRun.isBoldRequired ) || ( isItalicRequired != currentFontRun.isItalicRequired ) ) ) )
     {
       // Current run needs to be stored and a new one initialized.
 
@@ -706,8 +702,8 @@ void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
       currentFontRun.characterRun.characterIndex = currentFontRun.characterRun.characterIndex + currentFontRun.characterRun.numberOfCharacters;
       currentFontRun.characterRun.numberOfCharacters = 0u;
       currentFontRun.fontId = fontId;
-      currentFontRun.softwareItalic = needSoftwareItalic;
-      currentFontRun.softwareBold = needSoftwareBoldening;
+      currentFontRun.isBoldRequired = isBoldRequired;
+      currentFontRun.isItalicRequired = isItalicRequired;
     }
 
     // Add one more character to the run.
index 957fd8e..3fd324d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -44,7 +44,7 @@ AtlasGlyphManager::AtlasGlyphManager()
 }
 
 void AtlasGlyphManager::Add( const Text::GlyphInfo& glyph,
-                             const uint32_t outlineWidth,
+                             const Toolkit::AtlasGlyphManager::GlyphStyle& style,
                              const PixelData& bitmap,
                              Dali::Toolkit::AtlasManager::AtlasSlot& slot )
 {
@@ -63,9 +63,11 @@ void AtlasGlyphManager::Add( const Text::GlyphInfo& glyph,
 
   GlyphRecordEntry record;
   record.mIndex = glyph.index;
-  record.mOutlineWidth = outlineWidth;
   record.mImageId = slot.mImageId;
   record.mCount = 1;
+  record.mOutlineWidth = style.outline;
+  record.isItalic = style.isItalic;
+  record.isBold = style.isBold;
 
   // Have glyph records been created for this fontId ?
   bool foundGlyph = false;
@@ -99,9 +101,9 @@ void AtlasGlyphManager::GenerateMeshData( uint32_t imageId,
 }
 
 bool AtlasGlyphManager::IsCached( Text::FontId fontId,
-                                Text::GlyphIndex index,
-                                uint32_t outlineWidth,
-                                Dali::Toolkit::AtlasManager::AtlasSlot& slot )
+                                  Text::GlyphIndex index,
+                                  const Toolkit::AtlasGlyphManager::GlyphStyle& style,
+                                  Dali::Toolkit::AtlasManager::AtlasSlot& slot )
 {
   for ( std::vector< FontGlyphRecord >::iterator fontGlyphRecordIt = mFontGlyphRecords.begin();
         fontGlyphRecordIt != mFontGlyphRecords.end();
@@ -113,7 +115,10 @@ bool AtlasGlyphManager::IsCached( Text::FontId fontId,
             glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
             ++glyphRecordIt )
       {
-        if ( glyphRecordIt->mIndex == index && glyphRecordIt->mOutlineWidth == outlineWidth )
+        if ( ( glyphRecordIt->mIndex == index ) &&
+             ( glyphRecordIt->mOutlineWidth == style.outline ) &&
+             ( glyphRecordIt->isItalic == style.isItalic ) &&
+             ( glyphRecordIt->isBold == style.isBold ) )
         {
           slot.mImageId = glyphRecordIt->mImageId;
           slot.mAtlasId = mAtlasManager.GetAtlas( slot.mImageId );
@@ -174,7 +179,7 @@ const Toolkit::AtlasGlyphManager::Metrics& AtlasGlyphManager::GetMetrics()
   return mMetrics;
 }
 
-void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, uint32_t outlineWidth, int32_t delta )
+void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, const Toolkit::AtlasGlyphManager::GlyphStyle& style, int32_t delta )
 {
   if( 0 != delta )
   {
@@ -190,7 +195,10 @@ void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, Text::GlyphIn
               glyphRecordIt != fontGlyphRecordIt->mGlyphRecords.End();
               ++glyphRecordIt )
         {
-          if ( glyphRecordIt->mIndex == index && glyphRecordIt->mOutlineWidth == outlineWidth )
+          if ( ( glyphRecordIt->mIndex == index ) &&
+               ( glyphRecordIt->mOutlineWidth == style.outline ) &&
+               ( glyphRecordIt->isItalic == style.isItalic ) &&
+               ( glyphRecordIt->isBold == style.isBold ) )
           {
             glyphRecordIt->mCount += delta;
             DALI_ASSERT_DEBUG( glyphRecordIt->mCount >= 0 && "Glyph ref-count should not be negative" );
index 0d32834..3d2613e 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_TOOLKIT_ATLAS_GLYPH_MANAGER_IMPL_H__
-#define __DALI_TOOLKIT_ATLAS_GLYPH_MANAGER_IMPL_H__
+#ifndef DALI_TOOLKIT_ATLAS_GLYPH_MANAGER_IMPL_H
+#define DALI_TOOLKIT_ATLAS_GLYPH_MANAGER_IMPL_H
 
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -51,9 +51,11 @@ public:
   struct GlyphRecordEntry
   {
     Text::GlyphIndex mIndex;
-    uint32_t mOutlineWidth;
     uint32_t mImageId;
     int32_t mCount;
+    uint16_t mOutlineWidth;
+    bool isItalic:1;
+    bool isBold:1;
   };
 
   struct FontGlyphRecord
@@ -71,7 +73,7 @@ public:
    * @copydoc Toolkit::AtlasGlyphManager::Add
    */
   void Add( const Text::GlyphInfo& glyph,
-            const uint32_t outlineWidth,
+            const Toolkit::AtlasGlyphManager::GlyphStyle& style,
             const PixelData& bitmap,
             Dali::Toolkit::AtlasManager::AtlasSlot& slot );
 
@@ -87,7 +89,7 @@ public:
    */
   bool IsCached( Text::FontId fontId,
                  Text::GlyphIndex index,
-                 uint32_t outlineWidth,
+                 const Toolkit::AtlasGlyphManager::GlyphStyle& style,
                  Dali::Toolkit::AtlasManager::AtlasSlot& slot );
 
   /**
@@ -108,7 +110,7 @@ public:
   /**
    * @copydoc toolkit::AtlasGlyphManager::AdjustReferenceCount
    */
-  void AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, uint32_t outlineWidth, int32_t delta );
+  void AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, const Toolkit::AtlasGlyphManager::GlyphStyle& style, int32_t delta );
 
   /**
    * @copydoc Toolkit::AtlasGlyphManager::GetTextures
@@ -158,4 +160,4 @@ inline Internal::AtlasGlyphManager& GetImplementation(Toolkit::AtlasGlyphManager
 
 } // namespace Dali
 
-#endif // __DALI_TOOLKIT_ATLAS_GLYPH_MANAGER_IMPL_H__
+#endif // DALI_TOOLKIT_ATLAS_GLYPH_MANAGER_IMPL_H
index bd6850d..357f431 100644 (file)
@@ -1,5 +1,5 @@
  /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -69,11 +69,11 @@ AtlasGlyphManager::AtlasGlyphManager(Internal::AtlasGlyphManager *impl)
 }
 
 void AtlasGlyphManager::Add( const Text::GlyphInfo& glyph,
-                             const uint32_t outlineWidth,
+                             const GlyphStyle& style,
                              const PixelData& bitmap,
                              AtlasManager::AtlasSlot& slot )
 {
-  GetImplementation(*this).Add( glyph, outlineWidth, bitmap, slot );
+  GetImplementation(*this).Add( glyph, style, bitmap, slot );
 }
 
 void AtlasGlyphManager::GenerateMeshData( uint32_t imageId,
@@ -87,10 +87,10 @@ void AtlasGlyphManager::GenerateMeshData( uint32_t imageId,
 
 bool AtlasGlyphManager::IsCached( Text::FontId fontId,
                                   Text::GlyphIndex index,
-                                  uint32_t outlineWidth,
+                                  const GlyphStyle& style,
                                   AtlasManager::AtlasSlot& slot )
 {
-  return GetImplementation(*this).IsCached( fontId, index, outlineWidth, slot );
+  return GetImplementation(*this).IsCached( fontId, index, style, slot );
 }
 
 void AtlasGlyphManager::SetNewAtlasSize( uint32_t width, uint32_t height, uint32_t blockWidth, uint32_t blockHeight )
@@ -118,9 +118,9 @@ const Toolkit::AtlasGlyphManager::Metrics& AtlasGlyphManager::GetMetrics()
   return GetImplementation(*this).GetMetrics();
 }
 
-void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, uint32_t outlineWidth, int32_t delta )
+void AtlasGlyphManager::AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, const GlyphStyle& style, int32_t delta )
 {
-  GetImplementation(*this).AdjustReferenceCount( fontId, index, outlineWidth, delta );
+  GetImplementation(*this).AdjustReferenceCount( fontId, index, style, delta );
 }
 
 } // namespace Toolkit
index c41415e..592017b 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_TOOLKIT_ATLAS_GLYPH_MANAGER_H__
-#define __DALI_TOOLKIT_ATLAS_GLYPH_MANAGER_H__
+#ifndef DALI_TOOLKIT_ATLAS_GLYPH_MANAGER_H
+#define DALI_TOOLKIT_ATLAS_GLYPH_MANAGER_H
 
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -55,6 +55,19 @@ public:
     AtlasManager::Metrics mAtlasMetrics;    ///< metrics from the Atlas Manager
   };
 
+  struct GlyphStyle
+  {
+    GlyphStyle()
+    : outline{ 0u },
+      isItalic{ false },
+      isBold{ false }
+    {}
+
+    uint16_t outline; ///< The outline width of this glyph
+    bool isItalic:1;  ///< Whether the glyph is italic.
+    bool isBold:1;    ///< Whether the glyph is bold.
+  };
+
   /**
    * @brief Create a AtlasGlyphManager handle.
    *
@@ -80,12 +93,12 @@ public:
    * @brief Ask Atlas Manager to add a glyph
    *
    * @param[in] glyph glyph to add to an atlas
-   * @param[in] outlineWidth the outline width of the glyph
+   * @param[in] style The style of this glyph
    * @param[in] bitmap bitmap to use for glyph addition
    * @param[out] slot information returned by atlas manager for addition
    */
   void Add( const Text::GlyphInfo& glyph,
-            const uint32_t outlineWidth,
+            const GlyphStyle& style,
             const PixelData& bitmap,
             AtlasManager::AtlasSlot& slot );
 
@@ -105,14 +118,14 @@ public:
    *
    * @param[in] fontId The font that this glyph comes from
    * @param[in] index The GlyphIndex of this glyph
-   * @param[in] outlineWidth The outline width of this glyph
+   * @param[in] style The style of this glyph
    * @param[out] slot container holding information about the glyph( mImage = 0 indicates not being cached )
    *
    * @return Whether glyph is cached or not ?
    */
   bool IsCached( Text::FontId fontId,
                  Text::GlyphIndex index,
-                 uint32_t outlineWidth,
+                 const GlyphStyle& style,
                  AtlasManager::AtlasSlot& slot );
 
   /**
@@ -164,10 +177,10 @@ public:
    *
    * @param[in] fontId The font this image came from
    * @param[in] index The index of the glyph
-   * @param[in] outlineWidth The outline width of the glyph
+   * @param[in] style The style of this glyph
    * @param[in] delta The adjustment to make to the reference count
    */
-  void AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, uint32_t outlineWidth, int32_t delta );
+  void AdjustReferenceCount( Text::FontId fontId, Text::GlyphIndex index, const GlyphStyle& style, int32_t delta );
 
 private:
 
@@ -179,4 +192,4 @@ private:
 
 } // namespace Dali
 
-#endif // __DALI_TOOLKIT_ATLAS_GLYPH_MANAGER_H__
+#endif // DALI_TOOLKIT_ATLAS_GLYPH_MANAGER_H
index e06b958..dddb301 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -93,7 +93,7 @@ const float HALF( 0.5f );
 const float ONE( 1.0f );
 const uint32_t DEFAULT_ATLAS_WIDTH = 512u;
 const uint32_t DEFAULT_ATLAS_HEIGHT = 512u;
-const uint32_t NO_OUTLINE = 0;
+const uint16_t NO_OUTLINE = 0u;
 }
 
 struct AtlasRenderer::Impl
@@ -168,17 +168,21 @@ struct AtlasRenderer::Impl
   struct TextCacheEntry
   {
     TextCacheEntry()
-    : mFontId( 0 ),
-      mIndex( 0 ),
-      mOutlineWidth( 0 ),
-      mImageId( 0 )
+    : mFontId{ 0u },
+      mIndex{ 0u },
+      mImageId{ 0u },
+      mOutlineWidth{ 0u },
+      isItalic{ false },
+      isBold{ false }
     {
     }
 
     FontId mFontId;
     Text::GlyphIndex mIndex;
-    uint32_t mOutlineWidth;
     uint32_t mImageId;
+    uint16_t mOutlineWidth;
+    bool isItalic:1;
+    bool isBold:1;
   };
 
   Impl()
@@ -211,9 +215,9 @@ struct AtlasRenderer::Impl
     return false;
   }
 
-  void CacheGlyph( const GlyphInfo& glyph, FontId lastFontId, uint32_t outline, AtlasManager::AtlasSlot& slot )
+  void CacheGlyph( const GlyphInfo& glyph, FontId lastFontId, const AtlasGlyphManager::GlyphStyle& style, AtlasManager::AtlasSlot& slot )
   {
-    const bool glyphNotCached = !mGlyphManager.IsCached( glyph.fontId, glyph.index, outline, slot );  // Check FontGlyphRecord vector for entry with glyph index and fontId
+    const bool glyphNotCached = !mGlyphManager.IsCached( glyph.fontId, glyph.index, style, slot );  // Check FontGlyphRecord vector for entry with glyph index and fontId
 
     DALI_LOG_INFO( gLogFilter, Debug::Verbose, "AddGlyphs fontID[%u] glyphIndex[%u] [%s]\n", glyph.fontId, glyph.index, (glyphNotCached)?"not cached":"cached" );
 
@@ -243,7 +247,7 @@ struct AtlasRenderer::Impl
       PixelData bitmap;
 
       // Whether the glyph is an outline.
-      const bool isOutline = 0u != outline;
+      const bool isOutline = 0u != style.outline;
 
       // Whether the current glyph is a color one.
       const bool isColorGlyph = mFontClient.IsColorGlyph( glyph.fontId, glyph.index );
@@ -257,10 +261,10 @@ struct AtlasRenderer::Impl
 
         mFontClient.CreateBitmap( glyph.fontId,
                                   glyph.index,
-                                  glyph.softwareItalic,
-                                  glyph.softwareBold,
+                                  glyph.isItalicRequired,
+                                  glyph.isBoldRequired,
                                   glyphBufferData,
-                                  outline );
+                                  style.outline );
 
         // Create the pixel data.
         bitmap = PixelData::New( glyphBufferData.buffer,
@@ -292,21 +296,21 @@ struct AtlasRenderer::Impl
                                          blockSize.mNeededBlockHeight );
 
           // Locate a new slot for our glyph
-          mGlyphManager.Add( glyph, outline, bitmap, slot ); // slot will be 0 is glyph not added
+          mGlyphManager.Add( glyph, style, bitmap, slot ); // slot will be 0 is glyph not added
         }
       }
     }
     else
     {
       // We have 2+ copies of the same glyph
-      mGlyphManager.AdjustReferenceCount( glyph.fontId, glyph.index, outline, 1 ); //increment
+      mGlyphManager.AdjustReferenceCount( glyph.fontId, glyph.index, style, 1 ); //increment
     }
   }
 
   void GenerateMesh( const GlyphInfo& glyph,
                      const Vector2& position,
                      const Vector4& color,
-                     uint32_t outline,
+                     uint16_t outline,
                      AtlasManager::AtlasSlot& slot,
                      bool underlineGlyph,
                      float currentUnderlinePosition,
@@ -324,6 +328,8 @@ struct AtlasRenderer::Impl
     textCacheEntry.mImageId = slot.mImageId;
     textCacheEntry.mIndex = glyph.index;
     textCacheEntry.mOutlineWidth = outline;
+    textCacheEntry.isItalic = glyph.isItalicRequired;
+    textCacheEntry.isBold = glyph.isBoldRequired;
 
     newTextCache.PushBack( textCacheEntry );
 
@@ -445,7 +451,7 @@ struct AtlasRenderer::Impl
     const bool underlineEnabled = view.IsUnderlineEnabled();
     const Vector4& underlineColor( view.GetUnderlineColor() );
     const float underlineHeight = view.GetUnderlineHeight();
-    const unsigned int outlineWidth = view.GetOutlineWidth();
+    const uint16_t outlineWidth = view.GetOutlineWidth();
     const Vector4& outlineColor( view.GetOutlineColor() );
     const bool isOutline = 0u != outlineWidth;
 
@@ -528,13 +534,18 @@ struct AtlasRenderer::Impl
           lastUnderlinedFontId = glyph.fontId;
         } // underline
 
+        AtlasGlyphManager::GlyphStyle style;
+        style.isItalic = glyph.isItalicRequired;
+        style.isBold = glyph.isBoldRequired;
+
         // Retrieves and caches the glyph's bitmap.
-        CacheGlyph( glyph, lastFontId, NO_OUTLINE, slot );
+        CacheGlyph( glyph, lastFontId, style, slot );
 
         // Retrieves and caches the outline glyph's bitmap.
         if( isOutline )
         {
-          CacheGlyph( glyph, lastFontId, outlineWidth, slotOutline );
+          style.outline = outlineWidth;
+          CacheGlyph( glyph, lastFontId, style, slotOutline );
         }
 
         // Move the origin (0,0) of the mesh to the center of the actor
@@ -655,7 +666,11 @@ struct AtlasRenderer::Impl
   {
     for( Vector< TextCacheEntry >::Iterator oldTextIter = mTextCache.Begin(); oldTextIter != mTextCache.End(); ++oldTextIter )
     {
-      mGlyphManager.AdjustReferenceCount( oldTextIter->mFontId, oldTextIter->mIndex, oldTextIter->mOutlineWidth, -1/*decrement*/ );
+      AtlasGlyphManager::GlyphStyle style;
+      style.outline = oldTextIter->mOutlineWidth;
+      style.isItalic = oldTextIter->isItalic;
+      style.isBold = oldTextIter->isBold;
+      mGlyphManager.AdjustReferenceCount( oldTextIter->mFontId, oldTextIter->mIndex, style, -1/*decrement*/ );
     }
     mTextCache.Resize( 0 );
   }
index 8018054..de6b712 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -285,7 +285,7 @@ PixelData Typesetter::Render( const Vector2& size, Toolkit::DevelText::TextDirec
   // Retrieves the layout size.
   const Size& layoutSize = mModel->GetLayoutSize();
 
-  const float outlineWidth = mModel->GetOutlineWidth();
+  const int outlineWidth = static_cast<int>( mModel->GetOutlineWidth() );
 
   // Set the offset for the horizontal alignment according to the text direction and outline width.
   int penX = 0;
@@ -304,13 +304,13 @@ PixelData Typesetter::Render( const Vector2& size, Toolkit::DevelText::TextDirec
     }
     case HorizontalAlignment::END:
     {
-      penX += ( textDirection == Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT ) ? -outlineWidth * 2.0f : outlineWidth * 2.0f;
+      penX += ( textDirection == Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT ) ? -outlineWidth * 2 : outlineWidth * 2;
       break;
     }
   }
 
   // Set the offset for the vertical alignment.
-  int penY = 0;
+  int penY = 0u;
 
   switch( mModel->GetVerticalAlignment() )
   {
@@ -390,8 +390,8 @@ PixelData Typesetter::Render( const Vector2& size, Toolkit::DevelText::TextDirec
   {
 
     // Generate the outline if enabled
-    const float outlineWidth = mModel->GetOutlineWidth();
-    if ( outlineWidth > Math::MACHINE_EPSILON_1 )
+    const uint16_t outlineWidth = mModel->GetOutlineWidth();
+    if ( outlineWidth != 0u )
     {
       // Create the image buffer for outline
       Devel::PixelBuffer outlineImageBuffer = CreateImageBuffer( bufferWidth, bufferHeight, Typesetter::STYLE_OUTLINE, ignoreHorizontalAlignment, pixelFormat, penX, penY, 0u, numberOfGlyphs -1 );
@@ -505,7 +505,7 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth
     }
 
     // Retrieves the glyph's outline width
-    float outlineWidth = mModel->GetOutlineWidth();
+    float outlineWidth = static_cast<float>( mModel->GetOutlineWidth() );
 
     if( style == Typesetter::STYLE_OUTLINE )
     {
@@ -672,10 +672,10 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth
       {
         fontClient.CreateBitmap( glyphInfo->fontId,
                                  glyphInfo->index,
-                                 glyphInfo->softwareItalic,
-                                 glyphInfo->softwareBold,
+                                 glyphInfo->isItalicRequired,
+                                 glyphInfo->isBoldRequired,
                                  glyphData.glyphBitmap,
-                                 outlineWidth );
+                                 static_cast<int>( outlineWidth ) );
       }
 
 
index 3543fce..0a977f3 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -203,7 +203,7 @@ const Vector4& ViewModel::GetOutlineColor() const
   return mModel->GetOutlineColor();
 }
 
-float ViewModel::GetOutlineWidth() const
+uint16_t ViewModel::GetOutlineWidth() const
 {
   return mModel->GetOutlineWidth();
 }
@@ -332,12 +332,6 @@ void ViewModel::ElideGlyphs()
               glyphInfo = ellipsisGlyph;
 
               // Change the 'x' and 'y' position of the ellipsis glyph.
-
-              if( position.x > firstPenX )
-              {
-                position.x = firstPenX + removedGlypsWidth - ellipsisGlyphWidth;
-              }
-
               position.x += ellipsisGlyph.xBearing;
               position.y = penY - ellipsisGlyph.yBearing;
 
index 65cf48c..bc7d45f 100755 (executable)
@@ -191,7 +191,7 @@ public:
   /**
    * @copydoc ModelInterface::GetOutlineWidth()
    */
-  virtual float GetOutlineWidth() const;
+  virtual uint16_t GetOutlineWidth() const;
 
   /**
    * @copydoc ModelInterface::GetBackgroundColor()
index 624c443..593e1e5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -111,9 +111,13 @@ void ShapeText( const Vector<Character>& text,
   // There is no way to know the number of glyphs before shaping the text.
   // To avoid reallocations it's reserved space for a slightly biger number of glyphs than the number of characters.
 
+  GlyphInfo glyphInfo;
+  glyphInfo.isItalicRequired = false;
+  glyphInfo.isBoldRequired = false;
+
   const Length currentNumberOfGlyphs = glyphs.Count();
   const Length numberOfGlyphsReserved = static_cast<Length>( numberOfCharacters * 1.3f );
-  glyphs.Resize( currentNumberOfGlyphs + numberOfGlyphsReserved );
+  glyphs.Resize( currentNumberOfGlyphs + numberOfGlyphsReserved, glyphInfo );
   glyphToCharacterMap.Resize( currentNumberOfGlyphs + numberOfGlyphsReserved );
 
   // The actual number of glyphs.
@@ -137,8 +141,8 @@ void ShapeText( const Vector<Character>& text,
 
     currentFontId = fontRun.fontId;
     currentScript = scriptRun.script;
-    bool softwareItalic = fontRun.softwareItalic;
-    bool softwareBold = fontRun.softwareBold;
+    const bool isItalicRequired = fontRun.isItalicRequired;
+    const bool isBoldRequired = fontRun.isBoldRequired;
 
     // Get the min index to the last character of both runs.
     CharacterIndex currentIndex = min( fontRun.characterRun.characterIndex + fontRun.characterRun.numberOfCharacters,
@@ -174,8 +178,8 @@ void ShapeText( const Vector<Character>& text,
     Vector<CharacterIndex> tmpGlyphToCharacterMap;
 
     GlyphInfo glyphInfo;
-    glyphInfo.softwareItalic = softwareItalic;
-    glyphInfo.softwareBold = softwareBold;
+    glyphInfo.isItalicRequired = isItalicRequired;
+    glyphInfo.isBoldRequired = isBoldRequired;
 
     tmpGlyphs.Resize( numberOfGlyphs, glyphInfo );
     tmpGlyphToCharacterMap.Resize( numberOfGlyphs );
index 981d8cc..75a9e66 100755 (executable)
@@ -65,7 +65,7 @@ const char * const PLACEHOLDER_ELLIPSIS = "ellipsis";
 float ConvertToEven( float value )
 {
   int intValue(static_cast<int>( value ));
-  return static_cast<float>(intValue % 2 == 0) ? intValue : (intValue + 1);
+  return static_cast<float>( intValue + ( intValue & 1 ) );
 }
 
 } // namespace
@@ -556,7 +556,8 @@ void Controller::SetText( const std::string& text )
     mImpl->mModel->mVisualModel->SetTextColor( mImpl->mTextColor );
 
     MarkupProcessData markupProcessData( mImpl->mModel->mLogicalModel->mColorRuns,
-                                         mImpl->mModel->mLogicalModel->mFontDescriptionRuns );
+                                         mImpl->mModel->mLogicalModel->mFontDescriptionRuns,
+                                         mImpl->mModel->mLogicalModel->mEmbeddedItems );
 
     Length textSize = 0u;
     const uint8_t* utf8 = NULL;
@@ -1241,14 +1242,14 @@ const Vector4& Controller::GetOutlineColor() const
   return mImpl->mModel->mVisualModel->GetOutlineColor();
 }
 
-void Controller::SetOutlineWidth( unsigned int width )
+void Controller::SetOutlineWidth( uint16_t width )
 {
   mImpl->mModel->mVisualModel->SetOutlineWidth( width );
 
   mImpl->RequestRelayout();
 }
 
-unsigned int Controller::GetOutlineWidth() const
+uint16_t Controller::GetOutlineWidth() const
 {
   return mImpl->mModel->mVisualModel->GetOutlineWidth();
 }
@@ -2625,14 +2626,19 @@ bool Controller::KeyEvent( const Dali::KeyEvent& keyEvent )
     {
       DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::KeyEvent %p keyString %s\n", this, keyString.c_str() );
 
-      // InputMethodContext is no longer handling key-events
-      mImpl->ClearPreEditFlag();
+      if( !keyString.empty() )
+      {
+        // InputMethodContext is no longer handling key-events
+        mImpl->ClearPreEditFlag();
 
-      InsertText( keyString, COMMIT );
-      textChanged = true;
+        InsertText( keyString, COMMIT );
+
+        textChanged = true;
+
+        // Will request for relayout.
+        relayoutNeeded = true;
+      }
 
-      // Will request for relayout.
-      relayoutNeeded = true;
     }
 
     if ( ( mImpl->mEventData->mState != EventData::INTERRUPTED ) &&
@@ -3939,6 +3945,9 @@ void Controller::ResetText()
   // Reset buffers.
   mImpl->mModel->mLogicalModel->mText.Clear();
 
+  // Reset the embedded images buffer.
+  mImpl->mModel->mLogicalModel->ClearEmbeddedImages();
+
   // We have cleared everything including the placeholder-text
   mImpl->PlaceholderCleared();
 
index 33f1f8f..592b19d 100755 (executable)
@@ -861,14 +861,14 @@ public: // Default style & Input style
    *
    * @param[in] width The width in pixels of the outline, 0 indicates no outline
    */
-  void SetOutlineWidth( unsigned int width );
+  void SetOutlineWidth( uint16_t width );
 
   /**
    * @brief Retrieves the width of an outline
    *
    * @return The width of the outline.
    */
-  unsigned int GetOutlineWidth() const;
+  uint16_t GetOutlineWidth() const;
 
   /**
    * @brief Set the background color.
old mode 100644 (file)
new mode 100755 (executable)
index 2884119..e98e08e
@@ -51,6 +51,8 @@ typedef TextAbstraction::Script             Script;             ///< The charact
 typedef TextAbstraction::LineBreakInfo      LineBreakInfo;      ///< Line break info (must break, allow break, no break). Possible values are: @e LINE_MUST_BREAK, @e LINE_ALLOW_BREAK and @e LINE_NO_BREAK (in the TextAbstraction namespace).
 typedef TextAbstraction::WordBreakInfo      WordBreakInfo;      ///< Word break info (break, no break). Possible values are: @e WORD_BREAK and @e WORD_NO_BREAK (in the TextAbstraction namespace).
 typedef TextAbstraction::CharacterDirection CharacterDirection; ///< The character's direction: @e false is left to right, @e true is right to left.
+typedef TextAbstraction::ColorBlendingMode  ColorBlendingMode;  ///< Defines how a color is blended.
+typedef TextAbstraction::ColorIndex         ColorIndex;         ///< An index into an array of colors.
 
 typedef uint32_t                         GlyphIndex;                ///< An index into an array of glyphs.
 typedef uint32_t                         ScriptRunIndex;            ///< An index into an array of script runs.
@@ -60,7 +62,6 @@ typedef uint32_t                         BidirectionalRunIndex;     ///< An inde
 typedef uint32_t                         BidirectionalLineRunIndex; ///< An index into an array of bidirectional line info.
 typedef uint32_t                         LineIndex;                 ///< An index into an array of lines.
 typedef uint32_t                         ParagraphRunIndex;         ///< An index into an array of paragraphs.
-typedef uint32_t                         ColorIndex;                ///< An index into an array of colors.
 
 } // namespace Text
 
index f65655b..d5f8ff1 100755 (executable)
@@ -175,7 +175,7 @@ bool ParseOutlineProperties( const Property::Map& underlinePropertiesMap,
                                bool& colorDefined,
                                Vector4& color,
                                bool& widthDefined,
-                               unsigned int& width )
+                               uint16_t& width )
 {
   const unsigned int numberOfItems = underlinePropertiesMap.Count();
 
@@ -194,7 +194,7 @@ bool ParseOutlineProperties( const Property::Map& underlinePropertiesMap,
     {
       /// Width key.
       widthDefined = true;
-      width = static_cast<unsigned int>( valueGet.second.Get<float>() );
+      width = static_cast<uint16_t>( valueGet.second.Get<float>() );
     }
   }
 
@@ -358,16 +358,9 @@ void GetUnderlineProperties( ControllerPtr controller, Property::Value& value, E
         {
           Property::Map map;
 
-          const std::string enabledStr = enabled ? TRUE_TOKEN : FALSE_TOKEN;
-          map.Insert( ENABLE_KEY, enabledStr );
-
-          std::string colorStr;
-          Vector4ToColorString( color, colorStr );
-          map.Insert( COLOR_KEY, colorStr );
-
-          std::string heightStr;
-          FloatToString( height, heightStr );
-          map.Insert( HEIGHT_KEY, heightStr );
+          map.Insert( ENABLE_KEY, enabled );
+          map.Insert( COLOR_KEY, color );
+          map.Insert( HEIGHT_KEY, height );
 
           value = map;
         }
@@ -594,7 +587,7 @@ bool SetOutlineProperties( ControllerPtr controller, const Property::Value& valu
         bool colorDefined = false;
         Vector4 color;
         bool widthDefined = false;
-        unsigned int width = 0u;
+        uint16_t width = 0u;
 
         bool empty = true;
 
@@ -675,7 +668,7 @@ void GetOutlineProperties( ControllerPtr controller, Property::Value& value, Eff
         else
         {
           const Vector4& color = controller->GetOutlineColor();
-          const unsigned int width = controller->GetOutlineWidth();
+          const uint16_t width = controller->GetOutlineWidth();
 
           Property::Map map;
           map.Insert( COLOR_KEY, color );
index f2a82ad..a301d03 100755 (executable)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_TEXT_MODEL_INTERFACE_H
 
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -238,7 +238,7 @@ public:
    *
    * @return The width of the outline.
    */
-  virtual float GetOutlineWidth() const = 0;
+  virtual uint16_t GetOutlineWidth() const = 0;
 
   /**
    * @brief Retrieves the background color.
index 474b3ae..da87e0c 100755 (executable)
@@ -162,7 +162,7 @@ const Vector4& Model::GetOutlineColor() const
   return mVisualModel->GetOutlineColor();
 }
 
-float Model::GetOutlineWidth() const
+uint16_t Model::GetOutlineWidth() const
 {
   return mVisualModel->GetOutlineWidth();
 }
index f4fbd7b..3230e47 100755 (executable)
@@ -191,7 +191,7 @@ public:
   /**
    * @copydoc ModelInterface::GetOutlineWidth()
    */
-  virtual float GetOutlineWidth() const override;
+  virtual uint16_t GetOutlineWidth() const override;
 
   /**
    * @copydoc ModelInterface::GetBackgroundColor()
old mode 100644 (file)
new mode 100755 (executable)
index 96f9005..9e8020c
@@ -1,8 +1,8 @@
-#ifndef __DALI_TOOLKIT_TEXT_VIEW_INTERFACE_H__
-#define __DALI_TOOLKIT_TEXT_VIEW_INTERFACE_H__
+#ifndef DALI_TOOLKIT_TEXT_VIEW_INTERFACE_H
+#define DALI_TOOLKIT_TEXT_VIEW_INTERFACE_H
 
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -185,7 +185,7 @@ public:
    *
    * @return The width of the outline.
    */
-  virtual unsigned int GetOutlineWidth() const = 0;
+  virtual uint16_t GetOutlineWidth() const = 0;
 
 };
 
@@ -195,4 +195,4 @@ public:
 
 } // namespace Dali
 
-#endif // __DALI_TOOLKIT_TEXT_VIEW_INTERFACE_H__
+#endif // DALI_TOOLKIT_TEXT_VIEW_INTERFACE_H
old mode 100644 (file)
new mode 100755 (executable)
index 62c0008..929c17c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -411,7 +411,7 @@ const Vector4& View::GetOutlineColor() const
   return Vector4::ZERO;
 }
 
-unsigned int View::GetOutlineWidth() const
+uint16_t View::GetOutlineWidth() const
 {
   if( mImpl->mVisualModel )
   {
old mode 100644 (file)
new mode 100755 (executable)
index 51426de..e7d1942
@@ -1,8 +1,8 @@
-#ifndef __DALI_TOOLKIT_TEXT_VIEW_H__
-#define __DALI_TOOLKIT_TEXT_VIEW_H__
+#ifndef DALI_TOOLKIT_TEXT_VIEW_H
+#define DALI_TOOLKIT_TEXT_VIEW_H
 
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -139,7 +139,7 @@ public:
   /**
    * @copydoc Dali::Toolkit::Text::ViewInterface::GetOutlineWidth()
    */
-  virtual unsigned int GetOutlineWidth() const;
+  virtual uint16_t GetOutlineWidth() const;
 
 private:
 
@@ -160,4 +160,4 @@ private:
 
 } // namespace Dali
 
-#endif // __DALI_TOOLKIT_TEXT_VIEW_H__
+#endif // DALI_TOOLKIT_TEXT_VIEW_H
index bd567a4..3b1f5b7 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -373,7 +373,7 @@ void VisualModel::SetUnderlineHeight( float height )
   mUnderlineHeight = height;
 }
 
-void VisualModel::SetOutlineWidth( unsigned int width )
+void VisualModel::SetOutlineWidth( uint16_t width )
 {
   mOutlineWidth = width;
 }
@@ -428,7 +428,7 @@ float VisualModel::GetUnderlineHeight() const
   return mUnderlineHeight;
 }
 
-unsigned int VisualModel::GetOutlineWidth() const
+uint16_t VisualModel::GetOutlineWidth() const
 {
   return mOutlineWidth;
 }
@@ -473,8 +473,8 @@ VisualModel::VisualModel()
   mControlSize(),
   mShadowOffset(),
   mUnderlineHeight( 0.0f ),
-  mOutlineWidth( 0u ),
   mShadowBlurRadius( 0.0f ),
+  mOutlineWidth( 0u ),
   mNaturalSize(),
   mLayoutSize(),
   mCachedLineIndex( 0u ),
index 1cb6b4d..4b82cef 100755 (executable)
@@ -1,8 +1,8 @@
-#ifndef __DALI_TOOLKIT_TEXT_VISUAL_MODEL_IMPL_H__
-#define __DALI_TOOLKIT_TEXT_VISUAL_MODEL_IMPL_H__
+#ifndef DALI_TOOLKIT_TEXT_VISUAL_MODEL_IMPL_H
+#define DALI_TOOLKIT_TEXT_VISUAL_MODEL_IMPL_H
 
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -320,14 +320,14 @@ public:
    *
    * @param[in] width The width in pixels of the outline, 0 indicates no outline
    */
-  void SetOutlineWidth( unsigned int width );
+  void SetOutlineWidth( uint16_t width );
 
   /**
    * @brief Retrieves the width of an outline
    *
    * @return The width of the outline.
    */
-  unsigned int GetOutlineWidth() const;
+  uint16_t GetOutlineWidth() const;
 
   /**
    * @brief Sets the text's background color.
@@ -398,8 +398,8 @@ public:
   Size                   mControlSize;          ///< The size of the UI control.
   Vector2                mShadowOffset;         ///< Offset for drop shadow, 0 indicates no shadow
   float                  mUnderlineHeight;      ///< Fixed height for underline to override font metrics.
-  unsigned int           mOutlineWidth;         ///< Width of outline.
   float                  mShadowBlurRadius;     ///< Blur radius of shadow, 0 indicates no blur.
+  uint16_t           mOutlineWidth;         ///< Width of outline.
 
 private:
 
@@ -422,4 +422,4 @@ public:
 
 } // namespace Dali
 
-#endif // __DALI_TOOLKIT_TEXT_VISUAL_MODEL_IMPL_H__
+#endif // DALI_TOOLKIT_TEXT_VISUAL_MODEL_IMPL_H
index dbbb619..aed37a2 100644 (file)
@@ -45,8 +45,17 @@ namespace Internal
 namespace
 {
 
+constexpr auto LOOP_FOREVER = -1;
+
 const Dali::Vector4 FULL_TEXTURE_RECT( 0.f, 0.f, 1.f, 1.f );
 
+// Flags for re-sending data to the rasterize thread
+enum Flags
+{
+  RESEND_PLAY_RANGE  = 1 << 0,
+  RESEND_LOOP_COUNT  = 1 << 1
+};
+
 } // unnamed namespace
 
 AnimatedVectorImageVisualPtr AnimatedVectorImageVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, const Property::Map& properties )
@@ -70,7 +79,10 @@ AnimatedVectorImageVisual::AnimatedVectorImageVisual( VisualFactoryCache& factor
   mUrl( imageUrl ),
   mVectorRasterizeThread( imageUrl.GetUrl() ),
   mVisualSize(),
+  mPlayRange( 0.0f, 1.0f ),
   mPlacementActor(),
+  mLoopCount( LOOP_FOREVER ),
+  mResendFlag( 0 ),
   mActionStatus( DevelAnimatedVectorImageVisual::Action::STOP )
 {
   // the rasterized image is with pre-multiplied alpha format
@@ -99,9 +111,10 @@ void AnimatedVectorImageVisual::DoCreatePropertyMap( Property::Map& map ) const
   {
     map.Insert( Toolkit::ImageVisual::Property::URL, mUrl.GetUrl() );
   }
-  map.Insert( Toolkit::DevelImageVisual::Property::LOOP_COUNT, static_cast< int >( mVectorRasterizeThread.GetLoopCount() ) );
-  map.Insert( Toolkit::DevelImageVisual::Property::PLAY_RANGE, static_cast< Vector2 >( mVectorRasterizeThread.GetPlayRange() ) );
+  map.Insert( Toolkit::DevelImageVisual::Property::LOOP_COUNT, mLoopCount );
+  map.Insert( Toolkit::DevelImageVisual::Property::PLAY_RANGE, mPlayRange );
   map.Insert( Toolkit::DevelImageVisual::Property::PLAY_STATE, static_cast< int >( mVectorRasterizeThread.GetPlayState() ) );
+  map.Insert( Toolkit::DevelImageVisual::Property::CURRENT_PROGRESS, mVectorRasterizeThread.GetCurrentProgress() );
 }
 
 void AnimatedVectorImageVisual::DoCreateInstancePropertyMap( Property::Map& map ) const
@@ -142,7 +155,8 @@ void AnimatedVectorImageVisual::DoSetProperty( Property::Index index, const Prop
       int32_t loopCount;
       if( value.Get( loopCount ) )
       {
-        mVectorRasterizeThread.SetLoopCount( loopCount );
+        mLoopCount = loopCount;
+        mResendFlag |= RESEND_LOOP_COUNT;
       }
       break;
     }
@@ -151,7 +165,8 @@ void AnimatedVectorImageVisual::DoSetProperty( Property::Index index, const Prop
       Vector2 range;
       if( value.Get( range ) )
       {
-        mVectorRasterizeThread.SetPlayRange( range );
+        mPlayRange = range;
+        mResendFlag |= RESEND_PLAY_RANGE;
       }
       break;
     }
@@ -229,6 +244,8 @@ void AnimatedVectorImageVisual::OnSetTransform()
       mVectorRasterizeThread.SetSize( width, height );
     }
 
+    SendAnimationData();
+
     if( mActionStatus == DevelAnimatedVectorImageVisual::Action::PLAY )
     {
       mVectorRasterizeThread.PlayAnimation();
@@ -262,7 +279,7 @@ void AnimatedVectorImageVisual::OnDoAction( const Property::Index actionId, cons
   {
     case DevelAnimatedVectorImageVisual::Action::PLAY:
     {
-      if( IsOnStage() )
+      if( IsOnStage() && mVisualSize != Vector2::ZERO )
       {
         mVectorRasterizeThread.PlayAnimation();
 
@@ -294,6 +311,26 @@ void AnimatedVectorImageVisual::OnDoAction( const Property::Index actionId, cons
       mActionStatus = DevelAnimatedVectorImageVisual::Action::STOP;
       break;
     }
+    case DevelAnimatedVectorImageVisual::Action::JUMP_TO:
+    {
+      float progress;
+      if( attributes.Get( progress ) )
+      {
+        mVectorRasterizeThread.SetCurrentProgress( progress );
+      }
+      break;
+    }
+    case DevelAnimatedVectorImageVisual::Action::UPDATE_PROPERTY:
+    {
+      Property::Map* map = attributes.GetMap();
+      if( map )
+      {
+        DoSetProperties( *map );
+
+        SendAnimationData();
+      }
+      break;
+    }
   }
 }
 
@@ -306,9 +343,9 @@ void AnimatedVectorImageVisual::OnResourceReady()
     actor.AddRenderer( mImpl->mRenderer );
     // reset the weak handle so that the renderer only get added to actor once
     mPlacementActor.Reset();
-  }
 
-  ResourceReady( Toolkit::Visual::ResourceStatus::READY );
+    ResourceReady( Toolkit::Visual::ResourceStatus::READY );
+  }
 }
 
 void AnimatedVectorImageVisual::OnAnimationFinished()
@@ -326,6 +363,41 @@ void AnimatedVectorImageVisual::OnAnimationFinished()
   }
 }
 
+void AnimatedVectorImageVisual::SendAnimationData()
+{
+  if( mResendFlag )
+  {
+    bool isPlaying = false;
+    if( mVectorRasterizeThread.GetPlayState() == DevelImageVisual::PlayState::PLAYING )
+    {
+      mVectorRasterizeThread.PauseAnimation();
+      isPlaying = true;
+    }
+
+    if( mResendFlag & RESEND_LOOP_COUNT )
+    {
+      mVectorRasterizeThread.SetLoopCount( mLoopCount );
+    }
+
+    if( mResendFlag & RESEND_PLAY_RANGE )
+    {
+      mVectorRasterizeThread.SetPlayRange( mPlayRange );
+    }
+
+    if( isPlaying )
+    {
+      mVectorRasterizeThread.PlayAnimation();
+    }
+    else
+    {
+      mVectorRasterizeThread.RenderFrame();
+      Stage::GetCurrent().KeepRendering( 0.0f );
+    }
+
+    mResendFlag = 0;
+  }
+}
+
 } // namespace Internal
 
 } // namespace Toolkit
index 5d871f0..032bea2 100644 (file)
@@ -156,6 +156,11 @@ private:
    */
   void OnAnimationFinished();
 
+  /**
+   * @brief Send animation data to the rasterize thread.
+   */
+  void SendAnimationData();
+
   // Undefined
   AnimatedVectorImageVisual( const AnimatedVectorImageVisual& visual ) = delete;
 
@@ -167,7 +172,10 @@ private:
   VisualUrl                                    mUrl;
   VectorRasterizeThread                        mVectorRasterizeThread;
   Vector2                                      mVisualSize;
+  Vector2                                      mPlayRange;
   WeakHandle< Actor >                          mPlacementActor;
+  int32_t                                      mLoopCount;
+  uint32_t                                     mResendFlag;
   DevelAnimatedVectorImageVisual::Action::Type mActionStatus;
 };
 
index 35f485f..a5de71a 100644 (file)
@@ -22,8 +22,8 @@
 #include <dali/devel-api/adaptor-framework/thread-settings.h>
 #include <dali/integration-api/adaptors/adaptor.h>
 #include <dali/integration-api/debug.h>
-
-// INTERNAL INCLUDES
+#include <chrono>
+#include <thread>
 
 namespace Dali
 {
@@ -38,6 +38,7 @@ namespace
 {
 
 constexpr auto LOOP_FOREVER = -1;
+constexpr auto NANOSECONDS_PER_SECOND( 1e+9 );
 
 #if defined(DEBUG_ENABLED)
 Debug::Filter* gVectorAnimationLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_VECTOR_ANIMATION" );
@@ -54,7 +55,9 @@ VectorRasterizeThread::VectorRasterizeThread( const std::string& url )
   mAnimationFinishedTrigger(),
   mPlayRange( 0.0f, 1.0f ),
   mPlayState( DevelImageVisual::PlayState::STOPPED ),
+  mFrameDurationNanoSeconds( 0 ),
   mProgress( 0.0f ),
+  mFrameRate( 60.0f ),
   mCurrentFrame( 0 ),
   mTotalFrame( 0 ),
   mStartFrame( 0 ),
@@ -132,13 +135,6 @@ void VectorRasterizeThread::PlayAnimation()
   ConditionalWait::ScopedLock lock( mConditionalWait );
   if( mPlayState != DevelImageVisual::PlayState::PLAYING )
   {
-    if( mPlayState == DevelImageVisual::PlayState::STOPPED )
-    {
-      // Reset the current frame and the current loop
-      mCurrentFrame = mStartFrame;
-      mCurrentLoop = 0;
-    }
-
     mPlayState = DevelImageVisual::PlayState::PLAYING;
     mConditionalWait.Notify( lock );
 
@@ -153,6 +149,10 @@ void VectorRasterizeThread::StopAnimation()
   {
     mPlayState = DevelImageVisual::PlayState::STOPPED;
 
+    // Reset the current frame and the current loop
+    mCurrentFrame = mStartFrame;
+    mCurrentLoop = 0;
+
     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::StopAnimation: Stop\n" );
   }
 }
@@ -171,10 +171,14 @@ void VectorRasterizeThread::PauseAnimation()
 void VectorRasterizeThread::RenderFrame()
 {
   ConditionalWait::ScopedLock lock( mConditionalWait );
-  mNeedRender = true;
-  mConditionalWait.Notify( lock );
 
-  DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::RenderFrame: Render\n" );
+  if( !mResourceReady )
+  {
+    mNeedRender = true;
+    mConditionalWait.Notify( lock );
+
+    DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::RenderFrame: Render\n" );
+  }
 }
 
 void VectorRasterizeThread::SetResourceReadyCallback( EventThreadCallback* callback )
@@ -191,13 +195,15 @@ void VectorRasterizeThread::SetAnimationFinishedCallback( EventThreadCallback* c
 
 void VectorRasterizeThread::SetLoopCount( int32_t count )
 {
-  ConditionalWait::ScopedLock lock( mConditionalWait );
+  if( mLoopCount != count )
+  {
+    ConditionalWait::ScopedLock lock( mConditionalWait );
 
-  mLoopCount = count;
+    mLoopCount = count;
 
-  // Reset progress
-  mCurrentLoop = 0;
-  mCurrentFrame = mStartFrame;
+    // Reset progress
+    mCurrentLoop = 0;
+  }
 }
 
 int32_t VectorRasterizeThread::GetLoopCount() const
@@ -207,8 +213,6 @@ int32_t VectorRasterizeThread::GetLoopCount() const
 
 void VectorRasterizeThread::SetPlayRange( Vector2 range )
 {
-  ConditionalWait::ScopedLock lock( mConditionalWait );
-
   // Make sure the range specified is between 0.0 and 1.0
   if( range.x >= 0.0f && range.x <= 1.0f && range.y >= 0.0f && range.y <= 1.0f )
   {
@@ -219,12 +223,31 @@ void VectorRasterizeThread::SetPlayRange( Vector2 range )
       orderedRange = Vector2( range.y, range.x );
     }
 
-    mPlayRange = orderedRange;
-
-    if( mTotalFrame != 0 )
+    if( mPlayRange != orderedRange )
     {
-      mStartFrame = static_cast< uint32_t >( mPlayRange.x * mTotalFrame + 0.5f );
-      mEndFrame = static_cast< uint32_t >( mPlayRange.y * mTotalFrame + 0.5f );
+      ConditionalWait::ScopedLock lock( mConditionalWait );
+
+      mPlayRange = orderedRange;
+
+      if( mTotalFrame != 0 )
+      {
+        mStartFrame = static_cast< uint32_t >( mPlayRange.x * mTotalFrame + 0.5f );
+        mEndFrame = static_cast< uint32_t >( mPlayRange.y * mTotalFrame + 0.5f );
+
+        // If the current frame is out of the range, change the current frame also.
+        if( mStartFrame > mCurrentFrame )
+        {
+          mCurrentFrame = mStartFrame;
+
+          mResourceReady = false;
+        }
+        else if( mEndFrame < mCurrentFrame )
+        {
+          mCurrentFrame = mEndFrame;
+
+          mResourceReady = false;
+        }
+      }
     }
   }
 }
@@ -234,6 +257,30 @@ Vector2 VectorRasterizeThread::GetPlayRange() const
   return mPlayRange;
 }
 
+void VectorRasterizeThread::SetCurrentProgress( float progress )
+{
+  ConditionalWait::ScopedLock lock( mConditionalWait );
+
+  if( progress >= mPlayRange.x && progress <= mPlayRange.y )
+  {
+    mProgress = progress;
+
+    if( mTotalFrame != 0 )
+    {
+      mCurrentFrame = static_cast< uint32_t >( mTotalFrame * progress + 0.5f );
+    }
+
+    mResourceReady = false;
+
+    DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::SetCurrentProgress: progress = %f (%d)\n", progress, mCurrentFrame );
+  }
+}
+
+float VectorRasterizeThread::GetCurrentProgress() const
+{
+  return ( static_cast< float >( mCurrentFrame ) / static_cast< float >( mTotalFrame ) );
+}
+
 DevelImageVisual::PlayState VectorRasterizeThread::GetPlayState() const
 {
   return mPlayState;
@@ -269,16 +316,27 @@ bool VectorRasterizeThread::StartRender()
   mStartFrame = static_cast< uint32_t >( mPlayRange.x * mTotalFrame + 0.5f );
   mEndFrame = static_cast< uint32_t >( mPlayRange.y * mTotalFrame + 0.5f );
 
-  mCurrentFrame = mStartFrame;
+  mCurrentFrame = std::max( static_cast< uint32_t >( mTotalFrame * mProgress + 0.5f ), mStartFrame );
+
+  mFrameRate = mVectorRenderer.GetFrameRate();
+  mFrameDurationNanoSeconds = NANOSECONDS_PER_SECOND / mFrameRate;
 
-  DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::StartRender: Renderer is started [%d (%d, %d)]\n", mTotalFrame, mStartFrame, mEndFrame );
+  DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::StartRender: Renderer is started [%d, %f fps]\n", mTotalFrame, mFrameRate );
 
   return true;
 }
 
 void VectorRasterizeThread::Rasterize()
 {
-  DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::Rasterize: [%d]\n", mCurrentFrame );
+  bool needRender, resourceReady;
+
+  {
+    ConditionalWait::ScopedLock lock( mConditionalWait );
+    needRender = mNeedRender;
+    resourceReady = mResourceReady;
+  }
+
+  auto currentFrameStartTime = std::chrono::system_clock::now();
 
   // Rasterize
   mVectorRenderer.Render( mCurrentFrame );
@@ -300,6 +358,10 @@ void VectorRasterizeThread::Rasterize()
           // Animation is finished
           mPlayState = DevelImageVisual::PlayState::STOPPED;
 
+          // Reset the current frame and the current loop
+          mCurrentFrame = mStartFrame;
+          mCurrentLoop = 0;
+
           mAnimationFinishedTrigger->Trigger();
 
           DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::Rasterize: Animation is finished\n" );
@@ -312,15 +374,28 @@ void VectorRasterizeThread::Rasterize()
     }
   }
 
-  mNeedRender = false;
+  if( needRender )
+  {
+    mNeedRender = false;
+  }
 
-  if( !mResourceReady )
+  if( !resourceReady )
   {
     DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::Rasterize: Resource ready trigger\n" );
 
     mResourceReadyTrigger->Trigger();
     mResourceReady = true;
   }
+
+  auto timeToSleepUntil = currentFrameStartTime + std::chrono::nanoseconds( mFrameDurationNanoSeconds );
+
+#if defined(DEBUG_ENABLED)
+  auto sleepDuration = std::chrono::duration_cast< std::chrono::milliseconds >( timeToSleepUntil - std::chrono::system_clock::now() );
+
+  DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::Rasterize: [current = %d, sleep duration = %lld]\n", mCurrentFrame, sleepDuration.count() );
+#endif
+
+  std::this_thread::sleep_until( timeToSleepUntil );
 }
 
 } // namespace Internal
index f8d409b..3c8879e 100644 (file)
@@ -142,6 +142,18 @@ public:
    */
   bool IsResourceReady() const;
 
+  /**
+   * @brief Sets the progress of the animation.
+   * @param[in] progress The new progress as a normalized value between [0,1] or between the play range if specified.
+   */
+  void SetCurrentProgress( float progress );
+
+  /**
+   * @brief Retrieves the current progress of the animation.
+   * @return The current progress as a normalized value between [0,1]
+   */
+  float GetCurrentProgress() const;
+
 protected:
 
   /**
@@ -184,7 +196,9 @@ private:
   std::unique_ptr< EventThreadCallback > mAnimationFinishedTrigger;
   Vector2                     mPlayRange;
   DevelImageVisual::PlayState mPlayState;
+  int64_t                     mFrameDurationNanoSeconds;
   float                       mProgress;
+  float                       mFrameRate;
   uint32_t                    mCurrentFrame;
   uint32_t                    mTotalFrame;
   uint32_t                    mStartFrame;
index 3f4e763..77d06b7 100644 (file)
@@ -187,6 +187,7 @@ ImageVisual::ImageVisual( VisualFactoryCache& factoryCache,
   mLoading( false ),
   mOrientationCorrection( true )
 {
+  EnablePreMultipliedAlpha( mFactoryCache.GetPreMultiplyOnLoad() );
 }
 
 ImageVisual::ImageVisual( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const Image& image )
@@ -211,6 +212,7 @@ ImageVisual::ImageVisual( VisualFactoryCache& factoryCache, ImageVisualShaderFac
   mLoading( false ),
   mOrientationCorrection( true )
 {
+  EnablePreMultipliedAlpha( mFactoryCache.GetPreMultiplyOnLoad() );
 }
 
 ImageVisual::~ImageVisual()
@@ -683,7 +685,7 @@ void ImageVisual::LoadTexture( bool& atlasing, Vector4& atlasRect, TextureSet& t
     atlasUploadObserver = this;
   }
 
-  auto preMultiplyOnLoad = mFactoryCache.GetPreMultiplyOnLoad() && !mImpl->mCustomShader
+  auto preMultiplyOnLoad = IsPreMultipliedAlphaEnabled() && !mImpl->mCustomShader
     ? TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD
     : TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
 
@@ -811,6 +813,7 @@ void ImageVisual::DoSetOffStage( Actor& actor )
   if( mReleasePolicy == Toolkit::ImageVisual::ReleasePolicy::DETACHED )
   {
     RemoveTexture(); // If INVALID_TEXTURE_ID then removal will be attempted on atlas
+    mImpl->mResourceStatus = Toolkit::Visual::ResourceStatus::PREPARING;
   }
 
   if( mImageUrl.IsValid() )
@@ -952,39 +955,41 @@ void ImageVisual::UploadComplete( bool loadingSuccess, int32_t textureId, Textur
                                   const Vector4& atlasRectangle, bool preMultiplied )
 {
   Toolkit::Visual::ResourceStatus resourceStatus;
-  Actor actor = mPlacementActor.GetHandle();
-  if( actor )
+  if( mImpl->mRenderer )
   {
-    if( mImpl->mRenderer )
+    if( usingAtlas )
     {
-      if( usingAtlas )
-      {
-        mImpl->mRenderer.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, mAtlasRect );
-      }
+      mImpl->mRenderer.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, mAtlasRect );
+    }
 
-      EnablePreMultipliedAlpha( preMultiplied );
+    EnablePreMultipliedAlpha( preMultiplied );
 
+    Actor actor = mPlacementActor.GetHandle();
+    if( actor )
+    {
       actor.AddRenderer( mImpl->mRenderer );
       // reset the weak handle so that the renderer only get added to actor once
       mPlacementActor.Reset();
-      if( loadingSuccess )
-      {
-        Sampler sampler = Sampler::New();
-        sampler.SetWrapMode(  mWrapModeU, mWrapModeV  );
-        textureSet.SetSampler( 0u, sampler );
-        mImpl->mRenderer.SetTextures(textureSet);
-      }
-      else
-      {
-        Image brokenImage = mFactoryCache.GetBrokenVisualImage();
+    }
+
+    if( loadingSuccess )
+    {
+      Sampler sampler = Sampler::New();
+      sampler.SetWrapMode(  mWrapModeU, mWrapModeV  );
+      textureSet.SetSampler( 0u, sampler );
+      mImpl->mRenderer.SetTextures(textureSet);
+    }
+    else
+    {
+      Image brokenImage = mFactoryCache.GetBrokenVisualImage();
 
-        textureSet = TextureSet::New();
-        mImpl->mRenderer.SetTextures( textureSet );
+      textureSet = TextureSet::New();
+      mImpl->mRenderer.SetTextures( textureSet );
 
-        ApplyImageToSampler( brokenImage );
-      }
+      ApplyImageToSampler( brokenImage );
     }
   }
+
   // Storing TextureSet needed when renderer staged.
   if( ! mImpl->mRenderer )
   {
index 6ae1d8e..e1b162c 100755 (executable)
@@ -291,7 +291,7 @@ void NPatchVisual::LoadImages()
 {
   if( NPatchLoader::UNINITIALIZED_ID == mId && mImageUrl.IsLocalResource() )
   {
-    bool preMultiplyOnLoad = mFactoryCache.GetPreMultiplyOnLoad() && !mImpl->mCustomShader ? true : false;
+    bool preMultiplyOnLoad = IsPreMultipliedAlphaEnabled() && !mImpl->mCustomShader ? true : false;
 
     mId = mLoader.Load( mImageUrl.GetUrl(), mBorder, preMultiplyOnLoad );
 
@@ -434,6 +434,7 @@ NPatchVisual::NPatchVisual( VisualFactoryCache& factoryCache )
   mBorder(),
   mAuxiliaryImageAlpha( 0.0f )
 {
+  EnablePreMultipliedAlpha( mFactoryCache.GetPreMultiplyOnLoad() );
 }
 
 NPatchVisual::~NPatchVisual()
index 1ea95a9..3a32ddc 100644 (file)
@@ -1,5 +1,5 @@
  /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -79,6 +79,16 @@ namespace
 
 #ifdef DEBUG_ENABLED
 Debug::Filter* gTextureManagerLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_TEXTURE_MANAGER" );
+
+#define GET_LOAD_STATE_STRING( loadState ) \
+  loadState == TextureManager::NOT_STARTED ? "NOT_STARTED" :             \
+    loadState == TextureManager::LOADING ? "LOADING" :                   \
+    loadState == TextureManager::LOAD_FINISHED ? "LOAD_FINISHED" :       \
+    loadState == TextureManager::WAITING_FOR_MASK ? "WAITING_FOR_MASK" : \
+    loadState == TextureManager::UPLOADED ? "UPLOADED" :                 \
+    loadState == TextureManager::CANCELLED ? "CANCELLED" :               \
+    loadState == TextureManager::LOAD_FAILED ? "LOAD_FAILED" : "Unknown"
+
 #endif
 
 const uint32_t      DEFAULT_ATLAS_SIZE( 1024u );                     ///< This size can fit 8 by 8 images of average size 128 * 128
@@ -117,8 +127,10 @@ TextureManager::TextureManager()
   mAsyncRemoteLoaders( GetNumberOfRemoteLoaderThreads(), [&]() { return AsyncLoadingHelper(*this); } ),
   mExternalTextures(),
   mLifecycleObservers(),
+  mLoadQueue(),
   mBrokenImageUrl(""),
-  mCurrentTextureId( 0 )
+  mCurrentTextureId( 0 ),
+  mQueueLoadFlag(false)
 {
 }
 
@@ -242,13 +254,18 @@ TextureSet TextureManager::LoadTexture(
       }
 
       TextureManager::LoadState loadState = GetTextureStateInternal( textureId );
-      loadingStatus = ( loadState == TextureManager::LOADING );
-
       if( loadState == TextureManager::UPLOADED )
       {
         // UploadComplete has already been called - keep the same texture set
         textureSet = GetTextureSet( textureId );
       }
+
+      // If we are loading the texture, or waiting for the ready signal handler to complete, inform
+      // caller that they need to wait.
+      loadingStatus = ( loadState == TextureManager::LOADING ||
+                        loadState == TextureManager::NOT_STARTED ||
+                        mQueueLoadFlag );
+
     }
     else
     {
@@ -327,7 +344,7 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
 {
   // First check if the requested Texture is cached.
   const TextureHash textureHash = GenerateHash( url.GetUrl(), desiredSize, fittingMode, samplingMode, useAtlas,
-                                                maskTextureId, preMultiplyOnLoad );
+                                                maskTextureId );
 
   TextureManager::TextureId textureId = INVALID_TEXTURE_ID;
 
@@ -345,7 +362,7 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
       ++( mTextureInfoContainer[ cacheIndex ].referenceCount );
     }
     textureId = mTextureInfoContainer[ cacheIndex ].textureId;
-    DALI_LOG_INFO( gTextureManagerLogFilter, Debug::Concise, "TextureManager::RequestLoad( url=%s observer=%p ) Using cached texture id@%d, textureId=%d\n",
+    DALI_LOG_INFO( gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s observer=%p ) Using cached texture id@%d, textureId=%d\n",
                    url.GetUrl().c_str(), observer, cacheIndex, textureId );
   }
 
@@ -360,7 +377,7 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
                                                   preMultiply ) );
     cacheIndex = mTextureInfoContainer.size() - 1u;
 
-    DALI_LOG_INFO( gTextureManagerLogFilter, Debug::Concise, "TextureManager::RequestLoad( url=%s observer=%p ) New texture, cacheIndex:%d, textureId=%d\n",
+    DALI_LOG_INFO( gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s observer=%p ) New texture, cacheIndex:%d, textureId=%d\n",
                    url.GetUrl().c_str(), observer, cacheIndex, textureId );
   }
 
@@ -372,11 +389,8 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
   textureInfo.storageType = storageType;
   textureInfo.orientationCorrection = orientationCorrection;
 
-  DALI_LOG_INFO( gTextureManagerLogFilter, Debug::Concise, "TextureInfo loadState:%s\n",
-                 textureInfo.loadState == TextureManager::NOT_STARTED ? "NOT_STARTED" :
-                 textureInfo.loadState == TextureManager::LOADING ? "LOADING" :
-                 textureInfo.loadState == TextureManager::UPLOADED ? "UPLOADED" :
-                 textureInfo.loadState == TextureManager::CANCELLED ? "CANCELLED" : "Unknown" );
+  DALI_LOG_INFO( gTextureManagerLogFilter, Debug::General, "TextureInfo loadState:%s\n",
+                 GET_LOAD_STATE_STRING(textureInfo.loadState ) );
 
   // Force reloading of texture by setting loadState unless already loading or cancelled.
   if ( TextureManager::ReloadPolicy::FORCED == reloadPolicy && TextureManager::LOADING != textureInfo.loadState &&
@@ -394,8 +408,7 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
     case TextureManager::LOAD_FAILED: // Failed notifies observer which then stops observing.
     case TextureManager::NOT_STARTED:
     {
-      LoadTexture( textureInfo );
-      ObserveTexture( textureInfo, observer );
+      LoadOrQueueTexture( textureInfo, observer ); // If called inside NotifyObservers, queues until afterwards
       break;
     }
     case TextureManager::LOADING:
@@ -407,11 +420,7 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
     {
       if( observer )
       {
-        // The Texture has already loaded. The other observers have already been notified.
-        // We need to send a "late" loaded notification for this observer.
-        observer->UploadComplete( true, textureInfo.textureId, textureInfo.textureSet,
-                                  textureInfo.useAtlas, textureInfo.atlasRect,
-                                  textureInfo.preMultiplied );
+        LoadOrQueueTexture( textureInfo, observer );
       }
       break;
     }
@@ -440,12 +449,10 @@ void TextureManager::Remove( const TextureManager::TextureId textureId )
   {
     TextureInfo& textureInfo( mTextureInfoContainer[ textureInfoIndex ] );
 
-    DALI_LOG_INFO( gTextureManagerLogFilter, Debug::Concise, "TextureManager::Remove(%d) cacheIdx:%d loadState:%s\n",
-                   textureId, textureInfoIndex,
-                   textureInfo.loadState == TextureManager::NOT_STARTED ? "NOT_STARTED" :
-                   textureInfo.loadState == TextureManager::LOADING ? "LOADING" :
-                   textureInfo.loadState == TextureManager::UPLOADED ? "UPLOADED" :
-                   textureInfo.loadState == TextureManager::CANCELLED ? "CANCELLED" : "Unknown" );
+    DALI_LOG_INFO( gTextureManagerLogFilter, Debug::Concise,
+                   "TextureManager::Remove(%d) url:%s\n  cacheIdx:%d loadState:%s\n",
+                   textureId, textureInfo.url.GetUrl().c_str(),
+                   textureInfoIndex, GET_LOAD_STATE_STRING( textureInfo.loadState ) );
 
     // Decrement the reference count and check if this is the last user of this Texture.
     if( --textureInfo.referenceCount <= 0 )
@@ -624,32 +631,102 @@ void TextureManager::RemoveObserver( TextureManager::LifecycleObserver& observer
   DALI_ASSERT_DEBUG(endIter != mLifecycleObservers.End());
 }
 
+void TextureManager::LoadOrQueueTexture( TextureInfo& textureInfo, TextureUploadObserver* observer )
+{
+  switch( textureInfo.loadState )
+  {
+    case NOT_STARTED:
+    case LOAD_FAILED:
+    {
+      if( mQueueLoadFlag )
+      {
+        QueueLoadTexture( textureInfo, observer );
+      }
+      else
+      {
+        LoadTexture( textureInfo, observer );
+      }
+      break;
+    }
+    case LOADING:
+    case UPLOADED:
+    {
+      if( mQueueLoadFlag )
+      {
+        QueueLoadTexture( textureInfo, observer );
+      }
+      else
+      {
+        // The Texture has already loaded. The other observers have already been notified.
+        // We need to send a "late" loaded notification for this observer.
+        observer->UploadComplete( true, textureInfo.textureId, textureInfo.textureSet,
+                                  textureInfo.useAtlas, textureInfo.atlasRect,
+                                  textureInfo.preMultiplied );
+      }
+      break;
+    }
+    case CANCELLED:
+    case LOAD_FINISHED:
+    case WAITING_FOR_MASK:
+    {
+      break;
+    }
+  }
+}
 
-bool TextureManager::LoadTexture( TextureInfo& textureInfo )
+void TextureManager::QueueLoadTexture( TextureInfo& textureInfo, TextureUploadObserver* observer )
 {
-  bool success = true;
+  auto textureId = textureInfo.textureId;
+  mLoadQueue.PushBack( LoadQueueElement( textureId, observer) );
+}
 
-  if( textureInfo.loadState == NOT_STARTED )
+void TextureManager::LoadTexture( TextureInfo& textureInfo, TextureUploadObserver* observer )
+{
+  DALI_LOG_INFO( gTextureManagerLogFilter, Debug::Concise, "TextureManager::LoadTexture(): url:%s sync:%s\n",
+                 textureInfo.url.GetUrl().c_str(), textureInfo.loadSynchronously?"T":"F" );
+
+  textureInfo.loadState = LOADING;
+  if( !textureInfo.loadSynchronously )
   {
-    textureInfo.loadState = LOADING;
+    auto& loadersContainer = textureInfo.url.IsLocalResource() ? mAsyncLocalLoaders : mAsyncRemoteLoaders;
+    auto loadingHelperIt = loadersContainer.GetNext();
+    DALI_ASSERT_ALWAYS(loadingHelperIt != loadersContainer.End());
+    loadingHelperIt->Load(textureInfo.textureId, textureInfo.url,
+                          textureInfo.desiredSize, textureInfo.fittingMode,
+                          textureInfo.samplingMode, textureInfo.orientationCorrection );
+  }
+  ObserveTexture( textureInfo, observer );
+}
 
-    if( !textureInfo.loadSynchronously )
+void TextureManager::ProcessQueuedTextures()
+{
+  for( auto&& element : mLoadQueue )
+  {
+    int cacheIndex = GetCacheIndexFromId( element.mTextureId );
+    if( cacheIndex != INVALID_CACHE_INDEX )
     {
-      auto& loadersContainer = textureInfo.url.IsLocalResource() ? mAsyncLocalLoaders : mAsyncRemoteLoaders;
-      auto loadingHelperIt = loadersContainer.GetNext();
-      DALI_ASSERT_ALWAYS(loadingHelperIt != loadersContainer.End());
-      loadingHelperIt->Load(textureInfo.textureId, textureInfo.url,
-                            textureInfo.desiredSize, textureInfo.fittingMode,
-                            textureInfo.samplingMode, textureInfo.orientationCorrection );
+      TextureInfo& textureInfo( mTextureInfoContainer[cacheIndex] );
+      if( textureInfo.loadState == UPLOADED )
+      {
+        element.mObserver->UploadComplete( true, textureInfo.textureId, textureInfo.textureSet,
+                                           textureInfo.useAtlas, textureInfo.atlasRect,
+                                           textureInfo.preMultiplied );
+      }
+      else
+      {
+        LoadTexture( textureInfo, element.mObserver );
+      }
     }
   }
-
-  return success;
+  mLoadQueue.Clear();
 }
 
 void TextureManager::ObserveTexture( TextureInfo& textureInfo,
                                      TextureUploadObserver* observer )
 {
+  DALI_LOG_INFO( gTextureManagerLogFilter, Debug::Concise, "TextureManager::ObserveTexture(): url:%s observer:%p\n",
+                 textureInfo.url.GetUrl().c_str(), observer );
+
   if( observer )
   {
     textureInfo.observerList.PushBack( observer );
@@ -673,7 +750,9 @@ void TextureManager::AsyncLoadComplete( AsyncLoadingInfoContainerType& loadingCo
       {
         TextureInfo& textureInfo( mTextureInfoContainer[cacheIndex] );
 
-        DALI_LOG_INFO( gTextureManagerLogFilter, Debug::Concise, "  CacheIndex:%d LoadState: %d\n", cacheIndex, textureInfo.loadState );
+        DALI_LOG_INFO( gTextureManagerLogFilter, Debug::Concise,
+                       "  textureId:%d Url:%s CacheIndex:%d LoadState: %d\n",
+                       textureInfo.textureId, textureInfo.url.GetUrl().c_str(), cacheIndex, textureInfo.loadState );
 
         if( textureInfo.loadState != CANCELLED )
         {
@@ -788,12 +867,11 @@ void TextureManager::ApplyMask(
   }
 }
 
-
 void TextureManager::UploadTexture( Devel::PixelBuffer& pixelBuffer, TextureInfo& textureInfo )
 {
   if( textureInfo.useAtlas != USE_ATLAS )
   {
-    DALI_LOG_INFO( gTextureManagerLogFilter, Debug::Concise, "  TextureManager::UploadTexture() New Texture for textureId:%d\n", textureInfo.textureId );
+    DALI_LOG_INFO( gTextureManagerLogFilter, Debug::General, "  TextureManager::UploadTexture() New Texture for textureId:%d\n", textureInfo.textureId );
 
     // If the texture doesn't have an alpha channel, can't pre-multiply it.
     // Ensure that we don't change the load parameter (it's used for hashing), and instead set
@@ -828,53 +906,50 @@ void TextureManager::NotifyObservers( TextureInfo& textureInfo, bool success )
 
   // If there is an observer: Notify the load is complete, whether successful or not,
   // and erase it from the list
-  unsigned int observerCount = textureInfo.observerList.Count();
   TextureInfo* info = &textureInfo;
 
-  while( observerCount )
+  mQueueLoadFlag = true;
+
+  while( info->observerList.Count() )
   {
     TextureUploadObserver* observer = info->observerList[0];
 
     // During UploadComplete() a Control ResourceReady() signal is emitted.
     // During that signal the app may add remove /add Textures (e.g. via
-    // ImageViews).  At this point no more observers can be added to the
-    // observerList, because textureInfo.loadState = UPLOADED. However it is
-    // possible for observers to be removed, hence we check the observer list
-    // count every iteration.
-
-    // The reference to the textureInfo struct can also become invalidated,
-    // because new load requests can modify the mTextureInfoContainer list
-    // (e.g. if more requests are pushed back it can cause the list to be
-    // resized invalidating the reference to the TextureInfo ).
+    // ImageViews).
+    // It is possible for observers to be removed from the observer list,
+    // and it is also possible for the mTextureInfoContainer to be modified,
+    // invalidating the reference to the textureInfo struct.
+    // Texture load requests for the same URL are deferred until the end of this
+    // method.
+    DALI_LOG_INFO( gTextureManagerLogFilter, Debug::Concise, "NotifyObservers() url:%s loadState:%s\n",
+                   textureInfo.url.GetUrl().c_str(), GET_LOAD_STATE_STRING(textureInfo.loadState ) );
+
     observer->UploadComplete( success, info->textureId, info->textureSet, info->useAtlas, info->atlasRect,
                               info->preMultiplied );
     observer->DestructionSignal().Disconnect( this, &TextureManager::ObserverDestroyed );
 
-    // Get the textureInfo from the container again as it may have been
-    // invalidated,
-
+    // Get the textureInfo from the container again as it may have been invalidated.
     int textureInfoIndex = GetCacheIndexFromId( textureId );
     if( textureInfoIndex == INVALID_CACHE_INDEX)
     {
-      return; // texture has been removed - can stop.
+      break; // texture has been removed - can stop.
     }
-
     info = &mTextureInfoContainer[ textureInfoIndex ];
-    observerCount = info->observerList.Count();
-    if ( observerCount > 0 )
+
+    // remove the observer that was just triggered if it's still in the list
+    for( TextureInfo::ObserverListType::Iterator j = info->observerList.Begin(); j != info->observerList.End(); ++j )
     {
-      // remove the observer that was just triggered if it's still in the list
-      for( TextureInfo::ObserverListType::Iterator j = info->observerList.Begin(); j != info->observerList.End(); ++j )
+      if( *j == observer )
       {
-        if( *j == observer )
-        {
-          info->observerList.Erase( j );
-          observerCount--;
-          break;
-        }
+        info->observerList.Erase( j );
+        break;
       }
     }
   }
+
+  mQueueLoadFlag = false;
+  ProcessQueuedTextures();
 }
 
 TextureManager::TextureId TextureManager::GenerateUniqueTextureId()
@@ -903,8 +978,7 @@ TextureManager::TextureHash TextureManager::GenerateHash(
   const FittingMode::Type        fittingMode,
   const Dali::SamplingMode::Type samplingMode,
   const UseAtlas                 useAtlas,
-  TextureId                      maskTextureId,
-  TextureManager::MultiplyOnLoad preMultiplyOnLoad)
+  TextureId                      maskTextureId )
 {
   std::string hashTarget( url );
   const size_t urlLength = hashTarget.length();
@@ -964,22 +1038,6 @@ TextureManager::TextureHash TextureManager::GenerateHash(
     }
   }
 
-  auto premultipliedIndex = hashTarget.length();
-  hashTarget.resize( premultipliedIndex + 1 );
-  switch( preMultiplyOnLoad )
-  {
-    case TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD:
-    {
-      hashTarget[ premultipliedIndex ] = 't';
-      break;
-    }
-    case TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY:
-    {
-      hashTarget[ premultipliedIndex ] = 'f';
-      break;
-    }
-  }
-
   return Dali::CalculateHash( hashTarget );
 }
 
@@ -1004,21 +1062,24 @@ int TextureManager::FindCachedTexture(
     {
       // We have a match, now we check all the original parameters in case of a hash collision.
       TextureInfo& textureInfo( mTextureInfoContainer[i] );
-      auto multiplyOnLoad = textureInfo.preMultiplyOnLoad ? TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD :
-        TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
 
       if( ( url == textureInfo.url.GetUrl() ) &&
           ( useAtlas == textureInfo.useAtlas ) &&
           ( maskTextureId == textureInfo.maskTextureId ) &&
           ( size == textureInfo.desiredSize ) &&
-          ( preMultiplyOnLoad ==  multiplyOnLoad ) &&
           ( ( size.GetWidth() == 0 && size.GetHeight() == 0 ) ||
             ( fittingMode == textureInfo.fittingMode &&
               samplingMode == textureInfo.samplingMode ) ) )
       {
-        // The found Texture is a match.
-        cacheIndex = i;
-        break;
+        // 1. If preMultiplyOnLoad is MULTIPLY_ON_LOAD, then textureInfo.preMultiplyOnLoad should be true. The premultiplication result can be different.
+        // 2. If preMultiplyOnLoad is LOAD_WITHOUT_MULTIPLY, then textureInfo.preMultiplied should be false.
+        if( ( preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD && textureInfo.preMultiplyOnLoad )
+            || ( preMultiplyOnLoad == TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY && !textureInfo.preMultiplied ) )
+        {
+          // The found Texture is a match.
+          cacheIndex = i;
+          break;
+        }
       }
     }
   }
index 6df17c6..c64b781 100755 (executable)
@@ -424,6 +424,8 @@ private:
 
   typedef size_t TextureHash; ///< The type used to store the hash used for Texture caching.
 
+  // Structs:
+
   /**
    * @brief This struct is used to manage the life-cycle of Texture loading and caching.
    */
@@ -495,7 +497,20 @@ private:
     bool preMultiplied:1;          ///< true if the image's color was multiplied by it's alpha
   };
 
-  // Structs:
+  /**
+   * Structure to hold info about a texture load queued during NotifyObservers
+   */
+  struct LoadQueueElement
+  {
+    LoadQueueElement( TextureId textureId, TextureUploadObserver* observer )
+    : mTextureId( textureId ),
+      mObserver( observer )
+    {
+    }
+
+    TextureId mTextureId; ///< The texture id of the requested load.
+    TextureUploadObserver* mObserver; ///< Observer of texture load.
+  };
 
   /**
    * Struct to hold information about a requested Async load.
@@ -519,16 +534,35 @@ private:
   typedef std::vector<TextureInfo>      TextureInfoContainerType;       ///< The container type used to manage the life-cycle and caching of Textures
 
   /**
+   * @brief Initiate a load or queue load if NotifyObservers is invoking callbacks
+   * @param[in] textureInfo The TextureInfo struct associated with the Texture
+   * @param[in] observer The observer wishing to observe the texture upload
+   */
+  void LoadOrQueueTexture( TextureInfo& textureInfo, TextureUploadObserver* observer );
+
+  /**
+   * @brief Queue a texture load to be subsequently handled by ProcessQueuedTextures.
+   * @param[in] textureInfo The TextureInfo struct associated with the Texture
+   * @param[in] observer The observer wishing to observe the texture upload
+   */
+  void QueueLoadTexture( TextureInfo& textureInfo, TextureUploadObserver* observer );
+
+  /**
    * @brief Used internally to initiate a load.
    * @param[in] textureInfo The TextureInfo struct associated with the Texture
-   * @return                True if the load was initiated
+   * @param[in] observer The observer wishing to observe the texture upload
    */
-  bool LoadTexture( TextureInfo& textureInfo );
+  void LoadTexture( TextureInfo& textureInfo, TextureUploadObserver* observer );
+
+  /**
+   * @brief Initiate load of textures queued whilst NotifyObservers invoking callbacks.
+   */
+  void ProcessQueuedTextures();
 
   /**
    * Add the observer to the observer list
    * @param[in] textureInfo The TextureInfo struct associated with the texture
-   * observer The observer wishing to observe the texture upload
+   * @param[in] observer The observer wishing to observe the texture upload
    */
   void ObserveTexture( TextureInfo & textureInfo, TextureUploadObserver* observer );
 
@@ -631,8 +665,8 @@ private:
   TextureHash GenerateHash( const std::string& url, const ImageDimensions size,
                             const FittingMode::Type fittingMode,
                             const Dali::SamplingMode::Type samplingMode, const UseAtlas useAtlas,
-                            TextureId maskTextureId,
-                            MultiplyOnLoad preMultiplyOnLoad);
+                            TextureId maskTextureId );
+
   /**
    * @brief Looks up a cached texture by its hash.
    * If found, the given parameters are used to check there is no hash-collision.
@@ -747,8 +781,10 @@ private:  // Member Variables:
   RoundRobinContainerView< AsyncLoadingHelper > mAsyncRemoteLoaders;   ///< The Asynchronous image loaders used to provide all remote async loads
   std::vector< ExternalTextureInfo >            mExternalTextures;     ///< Externally provided textures
   Dali::Vector<LifecycleObserver*>              mLifecycleObservers;   ///< Lifecycle observers of texture manager
+  Dali::Vector<LoadQueueElement>                mLoadQueue;            ///< Queue of textures to load after NotifyObservers
   std::string                                   mBrokenImageUrl;       ///< Broken image url
   TextureId                                     mCurrentTextureId;     ///< The current value used for the unique Texture Id generation
+  bool                                          mQueueLoadFlag;        ///< Flag that causes Load Textures to be queued.
 };
 
 
index d30729b..2c8183c 100644 (file)
@@ -60,6 +60,10 @@ namespace Internal
 namespace
 {
 
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_CONTROL_VISUALS");
+#endif
+
 BaseHandle Create()
 {
   BaseHandle handle = Toolkit::VisualFactory::Get();
@@ -273,9 +277,19 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const Property::Map& property
     }
   }
 
+  DALI_LOG_INFO( gLogFilter, Debug::Concise, "VisualFactory::CreateVisual( VisualType:%s %s%s)\n",
+                 Scripting::GetEnumerationName<Toolkit::DevelVisual::Type>( visualType,
+                                                                            VISUAL_TYPE_TABLE,
+                                                                            VISUAL_TYPE_TABLE_COUNT ),
+                 visualType==Toolkit::DevelVisual::IMAGE?"url:":"",
+                 visualType==Toolkit::DevelVisual::IMAGE ?
+                 propertyMap.Find( Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME)->Get<std::string>().c_str()
+                 :"" );
+
+
   if( !visualPtr )
   {
-    DALI_LOG_ERROR( "Renderer type unknown\n" );
+    DALI_LOG_ERROR( "VisualType unknown\n" );
   }
 
   if( mDebugEnabled && visualType !=  Toolkit::DevelVisual::WIREFRAME )
index e0382b3..dfa8fef 100644 (file)
@@ -100,7 +100,9 @@ const char * const RELEASE_POLICY_NAME("releasePolicy");
 const char * const ORIENTATION_CORRECTION_NAME("orientationCorrection");
 const char * const AUXILIARY_IMAGE_NAME("auxiliaryImage");
 const char * const AUXILIARY_IMAGE_ALPHA_NAME("auxiliaryImageAlpha");
-const char * const PLAY_RANGE_NAME("playRange");
+const char * const PLAY_RANGE_NAME( "playRange" );
+const char * const PLAY_STATE_NAME( "playState" );
+const char * const CURRENT_PROGRESS_NAME( "currentProgress" );
 
 // Text visual
 const char * const TEXT_PROPERTY( "text" );
index 6ae808b..7e20d3b 100644 (file)
@@ -86,6 +86,8 @@ extern const char * const ORIENTATION_CORRECTION_NAME;
 extern const char * const AUXILLARY_IMAGE_NAME;
 extern const char * const AUXILLARY_IMAGE_ALPHA_NAME;
 extern const char * const PLAY_RANGE_NAME;
+extern const char * const PLAY_STATE_NAME;
+extern const char * const CURRENT_PROGRESS_NAME;
 
 // Text visual
 extern const char * const TEXT_PROPERTY;
index 79ab14d..e0d7b9a 100644 (file)
@@ -19,6 +19,7 @@
 #include <dali-toolkit/public-api/accessibility-manager/accessibility-manager.h>
 
 // EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
 #include <dali/devel-api/adaptor-framework/singleton-service.h>
 
 // INTERNAL INCLUDES
@@ -323,6 +324,8 @@ AccessibilityManager::AccessibilityActionSignalType& AccessibilityManager::Actio
 
 AccessibilityManager::AccessibilityActionSignalType& AccessibilityManager::ActionReadIndicatorInformationSignal()
 {
+  DALI_LOG_WARNING_NOFN("DEPRECATION WARNING: ActionReadIndicatorInformationSignal is deprecated and will be removed from next release.\n" );
+
   return GetImpl(*this).ActionReadIndicatorInformationSignal();
 }
 
index e3903e3..a8b2f8e 100755 (executable)
@@ -763,6 +763,7 @@ public:
   AccessibilityActionSignalType& ActionZoomSignal();
 
   /**
+   * @DEPRECATED_1_4.9
    * @brief This is emitted when accessibility action is received to read the information
    * in the indicator (by two fingers triple tap).
    *
index 4027521..1fa5040 100644 (file)
@@ -31,7 +31,7 @@ namespace Toolkit
 
 const unsigned int TOOLKIT_MAJOR_VERSION = 1;
 const unsigned int TOOLKIT_MINOR_VERSION = 4;
-const unsigned int TOOLKIT_MICRO_VERSION = 4;
+const unsigned int TOOLKIT_MICRO_VERSION = 10;
 const char * const TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index 3ed31e8..7954e5b 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
 **/
+
+/*
+ * In the original file, static analysis complains about return type from decode methods
+ * not being testable against Error constant (due to difference of type sizes).
+ *
+ * Modified decode methods to return error through an out parameter instead.
+ */
+
 #ifndef BASEN_HPP
 #define BASEN_HPP
 
@@ -92,14 +100,20 @@ struct b16_conversion_traits
         return dictionary[index];
     }
 
-    static char decode(char c)
+    /*
+     * In the original file, error code was passed through return value, but used int -1 (out of range of char).
+     * Separated error value from return value by using out parameter.
+     */
+    static char decode(char c, bool& error)
     {
+        error=false;
         if (c >= '0' && c <= '9') {
             return c - '0';
         } else if (c >= 'A' && c <= 'F') {
             return c - 'A' + 10;
         }
-        return Error;
+        error=true;
+        return 0;
     }
 };
 
@@ -117,14 +131,20 @@ struct b32_conversion_traits
         return dictionary[index];
     }
 
-    static char decode(char c)
+    /*
+     * In the original file, error code was passed through return value, but used int -1 (out of range of char).
+     * Separated error value from return value by using out parameter.
+     */
+    static char decode(char c, bool& error)
     {
+        error=false;
         if (c >= 'A' && c <= 'Z') {
             return c - 'A';
         } else if (c >= '2' && c <= '7') {
             return c - '2' + 26;
         }
-        return Error;
+        error=true;
+        return 0;
     }
 };
 
@@ -142,8 +162,13 @@ struct b64_conversion_traits
         return dictionary[index];
     }
 
-    static char decode(char c)
+    /*
+     * In the original file, error code was passed through return value, but used int -1 (out of range of char).
+     * Separated error value from return value by using out parameter.
+     */
+    static char decode(char c, bool& error)
     {
+        error=false;
         const int alph_len = 26;
         if (c >= 'A' && c <= 'Z') {
             return c - 'A';
@@ -156,7 +181,8 @@ struct b64_conversion_traits
         } else if (c == '/') {
             return c - '/' + alph_len * 2 + 11;
         }
-        return Error;
+        error=true;
+        return 0;
     }
 };
 
@@ -172,8 +198,14 @@ void decode(Iter1 start, Iter1 end, Iter2 out)
             ++iter;
             continue;
         }
-        char value = ConversionTraits::decode(*iter);
-        if (value == Error) {
+
+        /*
+         * In the original file, error value was out of range of return type.
+         * Separated error value from return value by using out parameter.
+         */
+        bool error=false;
+        char value = ConversionTraits::decode(*iter, error);
+        if (error) {
             // malformed data, but let's go on...
             ++iter;
             continue;
index b6e3c76..d8b6dd4 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali-toolkit
 Summary:    Dali 3D engine Toolkit
-Version:    1.4.4
+Version:    1.4.10
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT