[dali_1.3.36] Merge branch 'devel/master' 58/186558/1
authorGyörgy Straub <g.straub@partner.samsung.com>
Fri, 10 Aug 2018 09:12:09 +0000 (10:12 +0100)
committerGyörgy Straub <g.straub@partner.samsung.com>
Fri, 10 Aug 2018 09:12:09 +0000 (10:12 +0100)
Change-Id: Ibd53917b692116c08d792bacb38e577fa0f7dc2e

27 files changed:
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Shaping.cpp
automated-tests/src/dali-toolkit/CMakeLists.txt
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-text-abstraction.cpp
automated-tests/src/dali-toolkit/utc-Dali-GridLayout.cpp [new file with mode: 0644]
automated-tests/src/dali-toolkit/utc-Dali-KeyboardFocusManager.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp
dali-toolkit/devel-api/file.list
dali-toolkit/devel-api/focus-manager/keyboard-focus-manager-devel.cpp
dali-toolkit/devel-api/focus-manager/keyboard-focus-manager-devel.h
dali-toolkit/devel-api/layouting/grid.cpp [new file with mode: 0644]
dali-toolkit/devel-api/layouting/grid.h [new file with mode: 0644]
dali-toolkit/internal/file.list
dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp
dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.h
dali-toolkit/internal/image-loader/image-load-thread.cpp
dali-toolkit/internal/layouting/grid-impl.cpp [new file with mode: 0644]
dali-toolkit/internal/layouting/grid-impl.h [new file with mode: 0644]
dali-toolkit/internal/layouting/grid-locations.cpp [new file with mode: 0644]
dali-toolkit/internal/layouting/grid-locations.h [new file with mode: 0644]
dali-toolkit/internal/text/font-run.h
dali-toolkit/internal/text/multi-language-support-impl.cpp
dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp
dali-toolkit/internal/text/rendering/text-typesetter.cpp
dali-toolkit/internal/text/shaper.cpp
dali-toolkit/internal/visuals/svg/svg-rasterize-thread.cpp
dali-toolkit/public-api/dali-toolkit-version.cpp
packaging/dali-toolkit.spec

index e4464fd..0b7ca02 100644 (file)
@@ -55,6 +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 IsEqualGlyph ( const GlyphInfoData& glyphData, const GlyphInfo& glyph )
@@ -91,6 +93,14 @@ bool IsEqualGlyph ( const GlyphInfoData& glyphData, const GlyphInfo& glyph )
   {
     return false;
   }
+  if( glyphData.softwareItalic != glyph.softwareItalic )
+  {
+    return false;
+  }
+  if( glyphData.softwareBold != glyph.softwareBold )
+  {
+    return false;
+  }
 
   return true;
 }
@@ -107,6 +117,7 @@ struct ShapeInfoData
   Length*         charactersPerGlyph;                 ///< The characters per glyph.
   uint32_t        expectedNumberOfNewParagraphGlyphs; ///< The expected number of glyphs.
   GlyphIndex*     newParagraphGlyphs;                 ///< Indices to the new paragraphs glyphs.
+  Vector<FontDescriptionRun> fontDescriptions;        ///< Fonts which is used for text.
 };
 
 bool ShapeInfoTest( const ShapeInfoData& data )
@@ -122,7 +133,7 @@ bool ShapeInfoTest( const ShapeInfoData& data )
   const LayoutOptions options;
   CreateTextModel( data.text,
                    textArea,
-                   fontDescriptions,
+                   data.fontDescriptions,
                    options,
                    layoutSize,
                    logicalModel,
@@ -532,3 +543,151 @@ int UtcDaliTextShape(void)
   tet_result(TET_PASS);
   END_TEST;
 }
+
+int UtcDaliTextSoftwareStyling(void)
+{
+  tet_infoline(" UtcDaliTextSoftwareStyling");
+
+  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 },
+  };
+  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 },
+  };
+
+  CharacterIndex characterIndices[] = { 0u, 1u, 2u };
+  Length charactersPerGlyph[] = { 1u, 1u, 1u };
+
+  Vector<FontDescriptionRun> fontDescriptions01;
+  Vector<FontDescriptionRun> fontDescriptions02;
+
+  FontDescriptionRun fontDescriptionRun01 =
+  {
+    {
+      0u,
+      3u
+    },
+    NULL,
+    0u,
+    TextAbstraction::FontWeight::BOLD,
+    TextAbstraction::FontWidth::NONE,
+    TextAbstraction::FontSlant::ITALIC,
+    TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
+    false,
+    true,
+    false,
+    true,
+    false
+  };
+  fontDescriptions01.PushBack(fontDescriptionRun01);
+
+  FontDescriptionRun fontDescriptionRun02 =
+  {
+    {
+      0u,
+      1u
+    },
+    NULL,
+    0u,
+    TextAbstraction::FontWeight::NONE,
+    TextAbstraction::FontWidth::NONE,
+    TextAbstraction::FontSlant::NONE,
+    TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
+    false,
+    false,
+    false,
+    false,
+    false
+  };
+  FontDescriptionRun fontDescriptionRun03 =
+  {
+    {
+      1u,
+      1u
+    },
+    NULL,
+    0u,
+    TextAbstraction::FontWeight::BOLD,
+    TextAbstraction::FontWidth::NONE,
+    TextAbstraction::FontSlant::NONE,
+    TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
+    false,
+    true,
+    false,
+    false,
+    false
+  };
+  FontDescriptionRun fontDescriptionRun04 =
+  {
+    {
+      2u,
+      1u
+    },
+    NULL,
+    0u,
+    TextAbstraction::FontWeight::NONE,
+    TextAbstraction::FontWidth::NONE,
+    TextAbstraction::FontSlant::ITALIC,
+    TextAbstraction::FontClient::DEFAULT_POINT_SIZE,
+    false,
+    false,
+    false,
+    true,
+    false
+  };
+
+  fontDescriptions02.PushBack(fontDescriptionRun02);
+  fontDescriptions02.PushBack(fontDescriptionRun03);
+  fontDescriptions02.PushBack(fontDescriptionRun04);
+
+
+  struct ShapeInfoData data[] =
+  {
+    {
+      "Chiness script. Characters have same font description",
+      "未取得",
+      0u,
+      3u,
+      3u,
+      glyphs01,
+      characterIndices,
+      charactersPerGlyph,
+      0u,
+      NULL,
+      fontDescriptions01
+    },
+    {
+      "Chiness script. Each character has different font description.",
+      "未取得",
+      0u,
+      3u,
+      3u,
+      glyphs02,
+      characterIndices,
+      charactersPerGlyph,
+      0u,
+      NULL,
+      fontDescriptions02
+    }
+  };
+
+  const unsigned int numberOfTests = 2u;
+
+  for( unsigned int index = 0u; index < numberOfTests; ++index )
+  {
+    ToolkitTestApplication application;
+    if( !ShapeInfoTest( data[index] ) )
+    {
+      tet_result(TET_FAIL);
+    }
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
\ No newline at end of file
index 5852cfc..086f621 100755 (executable)
@@ -20,6 +20,7 @@ SET(TC_SOURCES
   utc-Dali-FlexContainer.cpp
   utc-Dali-FlexLayout.cpp
   utc-Dali-GaussianBlurView.cpp
+  utc-Dali-GridLayout.cpp
   utc-Dali-ImageView.cpp
   utc-Dali-ImageVisual.cpp
   utc-Dali-JsonParser.cpp
index 5cc9401..75312ef 100755 (executable)
@@ -152,7 +152,7 @@ public:
   void GetFontMetrics( FontId fontId, FontMetrics& metrics ){}
   GlyphIndex GetGlyphIndex( FontId fontId, Character charcode ){return 0;}
   bool GetGlyphMetrics( GlyphInfo* array, uint32_t size, bool horizontal ){return true;}
-  void CreateBitmap( FontId fontId, GlyphIndex glyphIndex, Dali::TextAbstraction::FontClient::GlyphBufferData& data, int outlineWidth ){}
+  void CreateBitmap( FontId fontId, GlyphIndex glyphIndex, bool softwareItailc, bool softwareBold, Dali::TextAbstraction::FontClient::GlyphBufferData& data, int outlineWidth ){}
   PixelData CreateBitmap( FontId fontId, GlyphIndex glyphIndex, int outlineWidth ){return PixelData();}
   void CreateVectorBlob( FontId fontId, GlyphIndex glyphIndex, VectorBlob*& blob,
                          unsigned int& blobLength, unsigned int& nominalWidth, unsigned int& nominalHeight )
@@ -472,9 +472,9 @@ bool FontClient::GetGlyphMetrics( GlyphInfo* array, uint32_t size, GlyphType typ
   return GetImplementation(*this).GetGlyphMetrics( array, size, horizontal );
 }
 
-void FontClient::CreateBitmap( FontId fontId, GlyphIndex glyphIndex, Dali::TextAbstraction::FontClient::GlyphBufferData& data, int outlineWidth )
+void FontClient::CreateBitmap( FontId fontId, GlyphIndex glyphIndex, bool softwareItailc, bool softwareBold, Dali::TextAbstraction::FontClient::GlyphBufferData& data, int outlineWidth )
 {
-  GetImplementation(*this).CreateBitmap( fontId, glyphIndex, data, outlineWidth );
+  GetImplementation(*this).CreateBitmap( fontId, glyphIndex, softwareItailc, softwareBold, data, outlineWidth );
 }
 
 PixelData FontClient::CreateBitmap( FontId fontId, GlyphIndex glyphIndex, int outlineWidth )
diff --git a/automated-tests/src/dali-toolkit/utc-Dali-GridLayout.cpp b/automated-tests/src/dali-toolkit/utc-Dali-GridLayout.cpp
new file mode 100644 (file)
index 0000000..4950241
--- /dev/null
@@ -0,0 +1,349 @@
+/*
+ * Copyright (c) 2018 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 <stdlib.h>
+#include <dali-toolkit-test-suite-utils.h>
+#include <toolkit-event-thread-callback.h>
+
+#include <dali-toolkit/dali-toolkit.h>
+#include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/devel-api/layouting/absolute-layout.h>
+#include <dali-toolkit/devel-api/layouting/grid.h>
+#include <dali-toolkit/devel-api/layouting/layout-item-impl.h>
+#include <dali-toolkit/devel-api/layouting/layout-group-impl.h>
+
+#include <../custom-layout.h>
+
+#include <layout-utils.h>
+
+using namespace Dali;
+using namespace Toolkit;
+
+void utc_dali_toolkit_grid_layouting_startup(void)
+{
+  test_return_value = TET_UNDEF;
+}
+
+void utc_dali_toolkit_grid_layouting_cleanup(void)
+{
+  test_return_value = TET_PASS;
+}
+
+int UtcDaliLayouting_GridLayout01(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliLayouting_GridLayout01 2 Column, 4 Items");
+
+  const auto NUMBER_OF_COLUMNS = 2;
+  const auto NUMBER_OF_ITEMS = 4;
+
+  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 );
+
+  std::vector< Control > controls;
+  for( auto i=0; i < NUMBER_OF_ITEMS; i++ )
+  {
+    controls.push_back( CreateLeafControl( 100, 100 ) );
+  }
+
+  for( auto&& iter : controls )
+  {
+    gridContainer.Add( iter );
+  }
+
+  rootControl.Add( gridContainer );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+ // Grid will layout first 2 items on first row then last 2 on second row.
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 100.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  // Item sizes will not be changed
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  tet_printf( "Confirm number of columns is as set\n");
+  DALI_TEST_EQUALS( gridLayout.GetNumberOfColumns(), NUMBER_OF_COLUMNS, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliLayouting_GridLayout02(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliLayouting_GridLayout02");
+
+  const auto NUMBER_OF_COLUMNS = 3;
+  const auto NUMBER_OF_ITEMS = 7;
+
+  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 );
+
+  std::vector< Control > controls;
+  for( auto i=0; i < NUMBER_OF_ITEMS; i++ )
+  {
+    controls.push_back( CreateLeafControl( 100, 100 ) );
+  }
+
+  for( auto&& iter : controls )
+  {
+    gridContainer.Add( iter );
+  }
+
+  rootControl.Add( gridContainer );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  // grid  layouts out 3 items per row, which is 480x800.
+  // Row 1
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 100.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 200.0f, 0.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  // Row 2
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[4].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[5].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 200.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  // Row 3
+  DALI_TEST_EQUALS( controls[6].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 200.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[4].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[5].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[6].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliLayouting_GridLayout03(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliLayouting_GridLayout03 Grid Padding");
+
+  const auto NUMBER_OF_COLUMNS = 2;
+  const auto NUMBER_OF_ITEMS = 4;
+
+  tet_printf( "Testing %d columns with %d items\n", NUMBER_OF_COLUMNS, NUMBER_OF_ITEMS );
+
+  Extents GRID_PADDING( Extents( 10, 10, 20, 20 ) ); // start,end,top,bottom
+
+  tet_printf( "Testing with Padding 10,10,20,20\n");
+
+  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 );
+  gridContainer.SetProperty( Control::Property::PADDING, GRID_PADDING );
+
+  std::vector< Control > controls;
+  for( auto i=0; i < NUMBER_OF_ITEMS; i++ )
+  {
+    controls.push_back( CreateLeafControl( 100, 100 ) );
+  }
+
+  for( auto&& iter : controls )
+  {
+    gridContainer.Add( iter );
+  }
+
+  rootControl.Add( gridContainer );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  tet_infoline(" UtcDaliLayouting_GridLayout03 Grid Padding 2 Column, 4 Items");
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f + GRID_PADDING.start , 0.0f + GRID_PADDING.top, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 100.0f + GRID_PADDING.start, 0.0f + GRID_PADDING.top, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f + GRID_PADDING.start, 100.0f + GRID_PADDING.top , 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 100.0f + GRID_PADDING.start, 100.0f + GRID_PADDING.top, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  tet_infoline(" UtcDaliLayouting_GridLayout03 Size of Grid should include padding");
+  DALI_TEST_EQUALS( gridContainer.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f * NUMBER_OF_COLUMNS + GRID_PADDING.start + + GRID_PADDING.end,
+                                                                                 100.0f * ( NUMBER_OF_ITEMS / NUMBER_OF_COLUMNS ) +
+                                                                                 GRID_PADDING.top + GRID_PADDING.bottom,
+                                                                                 0.0f ), 0.0001f, TEST_LOCATION );
+
+  tet_infoline(" UtcDaliLayouting_GridLayout03 Item sizes unchanged");
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliLayouting_GridLayout04(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliLayouting_GridLayout04 Child Margin");
+
+  const auto NUMBER_OF_COLUMNS = 2;
+  const auto NUMBER_OF_ITEMS = 4;
+
+  tet_printf( "Testing %d columns with %d items\n", NUMBER_OF_COLUMNS, NUMBER_OF_ITEMS );
+
+  Extents GRID_PADDING( Extents( 10, 10, 20, 20 ) ); // start,end,top,bottom
+  Extents ITEM_MARGIN( Extents( 10, 10, 5, 5 ) ); // start,end,top,bottom
+
+  tet_printf( "Testing with Margin 10,10,5,5\n");
+
+  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 );
+  gridContainer.SetProperty( Control::Property::PADDING, GRID_PADDING );
+
+  std::vector< Control > controls;
+  for( auto i=0; i < NUMBER_OF_ITEMS; i++ )
+  {
+    auto control = CreateLeafControl( 100, 100 );
+    control.SetProperty(Toolkit::Control::Property::MARGIN, ITEM_MARGIN );
+    controls.push_back( control );
+  }
+
+  for( auto&& iter : controls )
+  {
+    gridContainer.Add( iter );
+  }
+
+  rootControl.Add( gridContainer );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ),
+                    Vector3( 0.0f + GRID_PADDING.start + ITEM_MARGIN.start,
+                    0.0f + GRID_PADDING.top + ITEM_MARGIN.top,
+                    0.0f ),
+                    0.0001f, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ),
+                    Vector3( 100.0f + GRID_PADDING.start + ITEM_MARGIN.start *2 + ITEM_MARGIN.end,
+                    0.0f + GRID_PADDING.top + ITEM_MARGIN.top,
+                    0.0f ), 0.0001f, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ),
+                    Vector3( 0.0f + GRID_PADDING.start + ITEM_MARGIN.start,
+                    100.0f + GRID_PADDING.top + ITEM_MARGIN.top*2 + ITEM_MARGIN.bottom,
+                    0.0f ), 0.0001f, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ),
+                    Vector3( 100.0f + GRID_PADDING.start + ITEM_MARGIN.start*2 + ITEM_MARGIN.end,
+                    100.0f + GRID_PADDING.top + ITEM_MARGIN.top*2 + ITEM_MARGIN.bottom,
+                    0.0f ), 0.0001f, TEST_LOCATION );
+
+  tet_infoline(" UtcDaliLayouting_GridLayout03 Size of Grid should include padding and margins");
+
+  const auto NUMBER_OF_ROWS = ( NUMBER_OF_ITEMS / NUMBER_OF_COLUMNS );
+
+  DALI_TEST_EQUALS( gridContainer.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f * NUMBER_OF_COLUMNS + GRID_PADDING.start + GRID_PADDING.end +
+                                                                                          ITEM_MARGIN.start *NUMBER_OF_COLUMNS + ITEM_MARGIN.end *NUMBER_OF_COLUMNS,
+                                                                                          100.0f * NUMBER_OF_ROWS +
+                                                                                          GRID_PADDING.top + GRID_PADDING.bottom +
+                                                                                          ITEM_MARGIN.bottom *NUMBER_OF_ROWS + ITEM_MARGIN.bottom *NUMBER_OF_ROWS,
+                                                                                          0.0f ), 0.0001f, TEST_LOCATION );
+
+  tet_infoline(" UtcDaliLayouting_GridLayout03 Item sizes unchanged");
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  END_TEST;
+}
+
+
+int UtcDaliLayouting_GridLayoutDownCast(void)
+{
+  TestApplication application;
+  tet_infoline(" UtcDaliLayouting_GridLayoutDownCast - Testing Downcast");
+
+  Grid gridLayout = Grid::New();
+
+  LayoutGroup layoutGroup( gridLayout );
+
+  Grid gridLayoutCandidate = Grid::DownCast( layoutGroup );
+  DALI_TEST_CHECK( gridLayoutCandidate );
+
+  END_TEST;
+}
\ No newline at end of file
index 8b9547a..1b82c49 100755 (executable)
@@ -1425,3 +1425,39 @@ int UtcDaliKeyboardFocusManagerFocusedActorUnstaged(void)
 
   END_TEST;
 }
+
+int UtcDaliKeyboardFocusManagerEnableFocusIndicator(void)
+{
+  ToolkitTestApplication application;
+
+  tet_infoline( "Ensure we cannot set an actor to be focused if it is not staged and that we do not retrieve an actor if it has been unstaged" );
+
+  KeyboardFocusManager manager = KeyboardFocusManager::Get();
+  DALI_TEST_CHECK( ! manager.GetCurrentFocusActor() );
+
+  Actor actor = Actor::New();
+  actor.SetKeyboardFocusable( true );
+  Stage::GetCurrent().Add( actor );
+  manager.SetCurrentFocusActor( actor );
+
+  // Press Any key to notice physical keyboard event is comming to KeyboardFocusManager
+  // It makes mIsFocusIndicatorEnabled true and add focus indicator to focused actor.
+  Integration::KeyEvent rightEvent( "Right", "", 0, 0, 0, Integration::KeyEvent::Down, "", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE );
+  application.ProcessEvent(rightEvent);
+
+  Actor indicatorActor = manager.GetFocusIndicatorActor();
+
+  tet_infoline( "Indicator is added to focused actor" );
+  DALI_TEST_CHECK( actor == indicatorActor.GetParent() );
+
+  Dali::Toolkit::DevelKeyboardFocusManager::EnableFocusIndicator(manager, false);
+  DALI_TEST_CHECK( !Dali::Toolkit::DevelKeyboardFocusManager::IsFocusIndicatorEnabled(manager) );
+
+  tet_infoline( "Indicator is removed from focused actor because mUseFocusIndicator is false" );
+  DALI_TEST_CHECK( !indicatorActor.GetParent() );
+
+  END_TEST;
+}
+
+
+
index d5019bd..b134179 100644 (file)
@@ -1319,4 +1319,4 @@ int UtcDaliToolkitTextlabelVerticalLineAlignment(void)
   DALI_TEST_EQUALS( label.GetProperty< int >( DevelTextLabel::Property::VERTICAL_LINE_ALIGNMENT ), static_cast< int >( Toolkit::DevelText::VerticalLineAlignment::BOTTOM ), TEST_LOCATION );
 
   END_TEST;
-}
+}
\ No newline at end of file
index e974720..754c815 100755 (executable)
@@ -35,6 +35,7 @@ devel_api_src_files = \
   $(devel_api_src_dir)/layouting/flex-layout.cpp \
   $(devel_api_src_dir)/layouting/absolute-layout.cpp \
   $(devel_api_src_dir)/layouting/linear-layout.cpp \
+  $(devel_api_src_dir)/layouting/grid.cpp \
   $(devel_api_src_dir)/layouting/layout-item.cpp \
   $(devel_api_src_dir)/layouting/layout-item-impl.cpp \
   $(devel_api_src_dir)/layouting/layout-controller.cpp \
@@ -86,6 +87,7 @@ devel_api_layouting_header_files = \
   $(devel_api_src_dir)/layouting/absolute-layout.h \
   $(devel_api_src_dir)/layouting/child-layout-data.h \
   $(devel_api_src_dir)/layouting/flex-layout.h \
+  $(devel_api_src_dir)/layouting/grid.h \
   $(devel_api_src_dir)/layouting/linear-layout.h \
   $(devel_api_src_dir)/layouting/layout-child-impl.h \
   $(devel_api_src_dir)/layouting/layout-controller.h \
index a56ece5..17645b9 100644 (file)
@@ -33,6 +33,16 @@ void SetCustomAlgorithm(KeyboardFocusManager keyboardFocusManager, CustomAlgorit
   GetImpl(keyboardFocusManager).SetCustomAlgorithm(interface);
 }
 
+void EnableFocusIndicator(KeyboardFocusManager keyboardFocusManager, bool enable)
+{
+  GetImpl(keyboardFocusManager).EnableFocusIndicator(enable);
+}
+
+bool IsFocusIndicatorEnabled(KeyboardFocusManager keyboardFocusManager)
+{
+  return GetImpl(keyboardFocusManager).IsFocusIndicatorEnabled();
+}
+
 } // namespace DevelKeyboardFocusManager
 
 } // namespace Toolkit
index 4aa1887..dd59fcd 100644 (file)
@@ -71,6 +71,22 @@ public:
  */
 DALI_TOOLKIT_API void SetCustomAlgorithm(KeyboardFocusManager keyboardFocusManager, CustomAlgorithmInterface& interface);
 
+/**
+ * @brief Decide using focus indicator or not
+ *
+ * @param[in] keyboardFocusManager The instance of KeyboardFocusManager
+ * @param[in] enable Whether using focus indicator or not
+ */
+DALI_TOOLKIT_API void EnableFocusIndicator(KeyboardFocusManager keyboardFocusManager, bool enable);
+
+/**
+ * @brief Check focus indicator is enabled or not
+ *
+ * @param[in] keyboardFocusManager The instance of KeyboardFocusManager
+ * @return True when focus indicator is enabled
+ */
+DALI_TOOLKIT_API bool IsFocusIndicatorEnabled(KeyboardFocusManager keyboardFocusManager);
+
 } // namespace DevelKeyboardFocusManager
 
 } // namespace Toolkit
diff --git a/dali-toolkit/devel-api/layouting/grid.cpp b/dali-toolkit/devel-api/layouting/grid.cpp
new file mode 100644 (file)
index 0000000..1d9958d
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+//CLASS HEADER
+#include <dali-toolkit/devel-api/layouting/grid.h>
+
+//EXTERNAL HEADERS
+//INTERNAL HEADERS
+#include <dali-toolkit/internal/layouting/grid-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+
+Grid::Grid()
+{
+}
+
+Grid Grid::New()
+{
+  Internal::GridPtr internal = Internal::Grid::New();
+  return Grid( internal.Get() );
+}
+
+Grid Grid::DownCast( BaseHandle handle )
+{
+  return Grid( dynamic_cast< Dali::Toolkit::Internal::Grid*>( handle.GetObjectPtr() ) );
+}
+
+Grid::Grid( const Grid& other )
+: LayoutGroup( other )
+{
+}
+
+Grid& Grid::operator=( const Grid& other )
+{
+  if( &other != this )
+  {
+    LayoutGroup::operator=( other );
+  }
+  return *this;
+}
+
+void Grid::SetNumberOfColumns( int columns )
+{
+  GetImplementation(*this).SetNumberOfColumns( columns );
+}
+
+int Grid::GetNumberOfColumns() const
+{
+  return GetImplementation(*this).GetNumberOfColumns();
+}
+
+Grid::Grid( Dali::Toolkit::Internal::Grid* object )
+: LayoutGroup( object )
+{
+}
+
+} // namespace Toolkit
+} // namespace Dali
\ No newline at end of file
diff --git a/dali-toolkit/devel-api/layouting/grid.h b/dali-toolkit/devel-api/layouting/grid.h
new file mode 100644 (file)
index 0000000..e26b93f
--- /dev/null
@@ -0,0 +1,113 @@
+#ifndef DALI_TOOLKIT_LAYOUTING_GRID_LAYOUT_H
+#define DALI_TOOLKIT_LAYOUTING_GRID_LAYOUT_H
+
+/*
+ * Copyright (c) 2018 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/public-api/common/dali-common.h>
+#include <dali/public-api/object/base-handle.h>
+#include <dali-toolkit/devel-api/layouting/layout-group.h>
+#include <dali-toolkit/devel-api/layouting/layout-size.h>
+#include <dali-toolkit/public-api/toolkit-property-index-ranges.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+
+namespace Internal DALI_INTERNAL
+{
+class Grid;
+}
+
+/**
+ * @brief
+ * This class implements a horizontal box layout, automatically handling
+ * right to left or left to right direction change.
+ */
+class DALI_TOOLKIT_API Grid : public LayoutGroup
+{
+public:
+
+  /**
+   * @brief Creates an uninitialized Grid handle.
+   *
+   * Initialize it using Grid::New().
+   * Calling member functions with an uninitialized handle is not allowed.
+   */
+  Grid();
+
+  /**
+   * @brief Creates a Grid object.
+   */
+  static Grid New();
+
+  /**
+   * @brief Downcasts a handle to a Grid handle.
+   *
+   * If handle points to a Grid, the downcast produces a valid handle.
+   * If not, the returned handle is left uninitialized.
+
+   * @param[in] handle to an object
+   * @return Handle to a Grid or an uninitialized handle
+   */
+  static Grid DownCast( BaseHandle handle );
+
+  /**
+   * @brief Copy constructor
+   */
+  Grid( const Grid& other );
+
+  /**
+   * @brief Assigment operator
+   */
+  Grid& operator=( const Grid& other );
+
+  /**
+   * @brief Default destructor.
+   *
+   * This is non-virtual, since derived Handle types must not contain data or virtual methods
+   */
+  ~Grid()=default;
+
+  /**
+   * @brief Set the number of columns in the Grid.
+   * @param[in] columns number of columns,
+   */
+  void SetNumberOfColumns( int columns );
+
+  /**
+   *  @brief Get the number of columns in the grid.
+   *  @return the number of columns.
+   */
+  int GetNumberOfColumns() const;
+
+public: // Not intended for application developers
+
+  /// @cond internal
+  /**
+   * @brief This constructor is used by Grid::New() methods.
+   *
+   * @param[in] actor A pointer to a newly allocated Dali resource
+   */
+  explicit DALI_INTERNAL Grid( Internal::Grid* body );
+  /// @endcond
+};
+
+} // namespace Toolkit
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_LAYOUTING_GRID_LAYOUT_H
index 328d1d6..6475502 100755 (executable)
@@ -14,6 +14,8 @@ toolkit_src_files = \
    $(toolkit_src_dir)/layouting/flex-layout-impl.cpp \
    $(toolkit_src_dir)/layouting/absolute-layout-impl.cpp \
    $(toolkit_src_dir)/layouting/linear-layout-impl.cpp \
+   $(toolkit_src_dir)/layouting/grid-locations.cpp \
+   $(toolkit_src_dir)/layouting/grid-impl.cpp \
    $(toolkit_src_dir)/layouting/layout-item-data-impl.cpp \
    $(toolkit_src_dir)/layouting/layout-group-data-impl.cpp \
    $(toolkit_src_dir)/layouting/layout-controller-debug.cpp \
index 9e34984..a20808c 100644 (file)
@@ -123,6 +123,7 @@ KeyboardFocusManager::KeyboardFocusManager()
   mFocusGroupLoopEnabled( false ),
   mIsWaitingKeyboardFocusChangeCommit( false ),
   mClearFocusOnTouch( true ),
+  mEnableFocusIndicator( true ),
   mFocusHistory(),
   mSlotDelegate( this ),
   mCustomAlgorithmInterface(NULL)
@@ -178,7 +179,7 @@ bool KeyboardFocusManager::DoSetCurrentFocusActor( Actor actor )
   // Check whether the actor is in the stage and is keyboard focusable.
   if( actor && actor.IsKeyboardFocusable() && actor.OnStage() )
   {
-    if( mIsFocusIndicatorEnabled )
+    if( mIsFocusIndicatorEnabled && mEnableFocusIndicator )
     {
       actor.Add( GetFocusIndicatorActor() );
     }
@@ -836,8 +837,11 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event)
     Actor actor = GetCurrentFocusActor();
     if( actor )
     {
-      // Make sure the focused actor is highlighted
-      actor.Add( GetFocusIndicatorActor() );
+      if( mEnableFocusIndicator )
+      {
+        // Make sure the focused actor is highlighted
+        actor.Add( GetFocusIndicatorActor() );
+      }
     }
     else
     {
@@ -923,6 +927,21 @@ void KeyboardFocusManager::SetCustomAlgorithm(CustomAlgorithmInterface& interfac
   mCustomAlgorithmInterface = &interface;
 }
 
+void KeyboardFocusManager::EnableFocusIndicator(bool enable)
+{
+  if( !enable && mFocusIndicatorActor )
+  {
+    mFocusIndicatorActor.Unparent();
+  }
+
+  mEnableFocusIndicator = enable;
+}
+
+bool KeyboardFocusManager::IsFocusIndicatorEnabled() const
+{
+  return mEnableFocusIndicator;
+}
+
 } // namespace Internal
 
 } // namespace Toolkit
index ad87b55..be69ce0 100644 (file)
@@ -120,6 +120,16 @@ public:
    */
   void SetCustomAlgorithm(CustomAlgorithmInterface& interface);
 
+  /**
+   * @copydoc Toolkit::DevelKeyboardFocusManager::UseFocusIndicator
+   */
+  void EnableFocusIndicator(bool enable);
+
+  /**
+   * @copydoc Toolkit::DevelKeyboardFocusManager::UseFocusIndicator
+   */
+  bool IsFocusIndicatorEnabled() const;
+
 public:
 
   /**
@@ -267,6 +277,8 @@ private:
 
   bool mClearFocusOnTouch:1; ///< Whether clear focus on touch.
 
+  bool mEnableFocusIndicator;  ///< Whether use focus indicator
+
   FocusStack mFocusHistory; ///< Stack to contain pre-focused actor's BaseObject*
 
   SlotDelegate< KeyboardFocusManager > mSlotDelegate;
index 857a55b..74d3e39 100644 (file)
@@ -21,6 +21,7 @@
 // EXTERNAL INCLUDES
 #include <dali/devel-api/adaptor-framework/image-loading.h>
 #include <dali/integration-api/adaptors/adaptor.h>
+#include <dali/devel-api/adaptor-framework/thread-settings.h>
 
 namespace Dali
 {
@@ -74,6 +75,7 @@ ImageLoadThread::~ImageLoadThread()
 
 void ImageLoadThread::Run()
 {
+  SetThreadName( "ImageLoadThread" );
   mLogFactory.InstallLogFunction();
 
   while( LoadingTask* task = NextTaskToProcess() )
diff --git a/dali-toolkit/internal/layouting/grid-impl.cpp b/dali-toolkit/internal/layouting/grid-impl.cpp
new file mode 100644 (file)
index 0000000..a83ed99
--- /dev/null
@@ -0,0 +1,270 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+//CLASS HEADER
+#include <dali-toolkit/internal/layouting/grid-impl.h>
+
+//EXTERNAL HEADERS
+#include <dali/integration-api/debug.h>
+#include <dali/public-api/common/extents.h>
+#include <dali/public-api/actors/actor.h>
+
+//INTERNAL HEADERS
+#include <dali-toolkit/devel-api/layouting/layout-item.h>
+#include <dali-toolkit/public-api/controls/control-impl.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
+#include <dali-toolkit/devel-api/layouting/layout-length.h>
+#include <dali-toolkit/internal/layouting/grid-locations.h>
+
+#if defined(DEBUG_ENABLED)
+static Debug::Filter* gLogFilter = Debug::Filter::New( Debug::Concise, false, "LOG_LAYOUT" );
+#endif
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+
+GridPtr Grid::New()
+{
+  GridPtr layout( new Grid() );
+  return layout;
+}
+
+Grid::Grid()
+: LayoutGroup(),
+  mTotalHeight( 0 ),
+  mTotalWidth( 0 ),
+  mNumColumns( AUTO_FIT ),
+  mNumRows( AUTO_FIT ),
+  mRequestedColumnWidth( 0 ),
+  mRequestedNumColumns( AUTO_FIT )
+{
+  mLocations = GridLocations::New();
+}
+
+Grid::~Grid(){}
+
+void Grid::SetNumberOfColumns( int columns )
+{
+  mRequestedNumColumns = columns;
+  // Store value and Relayout if changed.
+  if( columns != mNumColumns )
+  {
+    mNumColumns = columns;
+    RequestLayout();
+  }
+}
+
+int Grid::GetNumberOfColumns() const
+{
+  return mNumColumns;
+}
+
+void Grid::DetermineNumberOfColumns( int availableSpace )
+{
+  if( mRequestedNumColumns == AUTO_FIT )
+  {
+    if( availableSpace > 0 )
+    {
+      // Can only calculate number of columns if a column width has been set
+      mNumColumns = ( mRequestedColumnWidth > 0 ) ? ( availableSpace / mRequestedColumnWidth ) : 1;
+    }
+  }
+}
+
+void Grid::OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec )
+{
+  DALI_LOG_STREAM( gLogFilter, Debug::Verbose,
+                   "Grid::OnMeasure Actor Id:" <<  Actor::DownCast(GetOwner()).GetId() <<
+                   " Owner:" <<  Actor::DownCast(GetOwner()).GetName() <<
+                   " MeasureSpecs( width:"<<widthMeasureSpec<<", height:"<<heightMeasureSpec );
+
+  auto gridWidthMode = widthMeasureSpec.GetMode();
+  auto gridHeightMode = heightMeasureSpec.GetMode();
+  LayoutLength widthSize = widthMeasureSpec.GetSize();
+  LayoutLength heightSize = heightMeasureSpec.GetSize();
+
+  int availableContentWidth(0);
+  int availableContentHeight(0);
+
+  LayoutLength desiredChildHeight( 0 );
+  LayoutLength desiredChildWidth( 0 );
+
+  Extents gridLayoutPadding = GetPadding();
+
+  auto childCount = GetChildCount();
+
+  // WIDTH SPECIFICATIONS
+
+  // measure first child and use it's dimensions for layout measurement
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Grid::OnMeasure MeasureSpec::Mode::EXACTLY or MeasureSpec::Mode::AT_MOST \n" );
+
+  if( childCount > 0 )
+  {
+    auto childLayoutItem = GetChildAt( 0 );
+    if( childLayoutItem )
+    {
+      auto childOwner = childLayoutItem->GetOwner();
+
+      MeasureChild( childLayoutItem, widthMeasureSpec, heightMeasureSpec );
+      desiredChildHeight = childLayoutItem->GetMeasuredHeight();
+      desiredChildWidth = childLayoutItem->GetMeasuredWidth();
+
+      // If child has a margin then add it to desired size
+      Extents childMargin = childOwner.GetProperty<Extents>( Toolkit::Control::Property::MARGIN );
+      desiredChildHeight += childMargin.top + childMargin.bottom;
+      desiredChildWidth += childMargin.start + childMargin.end;
+
+      mTotalWidth = desiredChildWidth * mNumColumns;
+      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Grid::OnMeasure TotalDesiredWidth(%d) \n", mTotalWidth.mValue );
+    } // Child is LayoutItem
+  } // Child exists
+
+  // Include padding for max and min checks
+  mTotalWidth += gridLayoutPadding.start + gridLayoutPadding.end;
+
+  // Ensure width does not exceed specified atmost width or less than mininum width
+  mTotalWidth = std::max( mTotalWidth, GetSuggestedMinimumWidth() );
+
+  // widthMode EXACTLY so grid must be the given width
+  if( gridWidthMode == MeasureSpec::Mode::EXACTLY || gridWidthMode == MeasureSpec::Mode::AT_MOST )
+  {
+    // In the case of AT_MOST, widthSize is the max limit.
+      mTotalWidth = std::min( mTotalWidth, widthSize );
+  }
+
+  availableContentWidth = mTotalWidth - gridLayoutPadding.start - gridLayoutPadding.end;
+  widthSize = mTotalWidth;
+
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Grid::OnMeasure availableContentWidth(%d) mTotalWidth(%d) \n",
+                 availableContentWidth,
+                 mTotalWidth.mValue );
+  // HEIGHT SPECIFICATIONS
+
+  // heightMode EXACTLY so grid must be the given height
+  if( gridHeightMode == MeasureSpec::Mode::EXACTLY || gridHeightMode == MeasureSpec::Mode::AT_MOST )
+  {
+    if( childCount > 0 )
+    {
+      mTotalHeight = gridLayoutPadding.top + gridLayoutPadding.bottom;
+
+      for( auto i = 0u; i < childCount; i += mNumColumns )
+      {
+        mTotalHeight += desiredChildHeight;
+      }
+      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Grid::OnMeasure TotalDesiredHeight(%d) \n",
+                      mTotalHeight.mValue );
+
+      // Ensure ourHeight does not exceed specified atmost height
+      mTotalHeight = std::min( mTotalHeight, heightSize );
+      mTotalHeight = std::max( mTotalHeight, GetSuggestedMinimumHeight() );
+
+      heightSize = mTotalHeight;
+    } // Child exists
+
+    // In the case of AT_MOST, availableContentHeigth is the max limit.
+    availableContentHeight = heightSize - gridLayoutPadding.top - gridLayoutPadding.bottom;
+  }
+  else
+  {
+    // Grid expands to fit content
+
+    // If number of columns AUTO_FIT then set to 1 column.
+
+    // Calculate numbers of rows, round down result as later check for remainder.
+    mNumRows = childCount / ( ( mNumColumns ) ? mNumColumns : 1 );
+    // If number of cells not cleanly dividable by colums, add another row to house remainder cells.
+    mNumRows += ( childCount %  ( ( mNumColumns ) ? mNumColumns : 1 ) ) ? 1 : 0;
+
+    availableContentHeight = desiredChildHeight * mNumRows;
+  }
+
+  // If number of columns not defined
+  DetermineNumberOfColumns( availableContentWidth );
+
+  // Locations define the start, end,top and bottom of each cell.
+  mLocations->CalculateLocations( mNumColumns, availableContentWidth, availableContentHeight, childCount, 0, 0 );
+
+
+  SetMeasuredDimensions( ResolveSizeAndState( widthSize, widthMeasureSpec, MeasuredSize::State::MEASURED_SIZE_OK ),
+                         ResolveSizeAndState( heightSize, heightMeasureSpec,  MeasuredSize::State::MEASURED_SIZE_OK ) );
+}
+
+void Grid::OnLayout( bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom )
+{
+  auto owner = GetOwner();
+  auto actor = Actor::DownCast(owner);
+  auto count = GetChildCount();
+
+  GridLocations::LocationVector locations =  mLocations->GetLocations();
+
+  Extents gridLayoutPadding = GetPadding();
+  Extents childMargins;
+
+  // Margin for all children dependant on if set on first child
+  if( count )
+  {
+    LayoutItemPtr childLayout = GetChildAt( 0 );
+    if( childLayout )
+    {
+      auto childOwner = childLayout->GetOwner();
+      if( childOwner )
+      {
+        childMargins = childOwner.GetProperty<Extents>( Toolkit::Control::Property::MARGIN );
+      }
+    }
+  }
+
+  for( unsigned int i = 0; i < count; i++)
+  {
+    // for each child
+    int childIndex = i;
+    LayoutItemPtr childLayout = GetChildAt( childIndex );
+    if( childLayout != nullptr )
+    {
+      // Get start and end position of child x1,x2
+      auto x1 = locations[ i ].xStart;
+      auto x2 = locations[ i ].xEnd;
+
+      // Get top and bottom position of child y1,y2
+      auto y1 = locations[ i ].yTop;
+      auto y2 = locations[ i ].yBottom;
+
+      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Grid::OnLayout cellSize(%d,%d) \n", x2 - x1,  y2 - y1);
+
+      // Offset children by the grids padding if present
+      x1 += gridLayoutPadding.start;
+      x2 += gridLayoutPadding.start;
+      y1 += gridLayoutPadding.top;
+      y2 += gridLayoutPadding.top;
+
+      // Offset children by the margin of the first child ( if required ).
+      x1 += childMargins.start;
+      x2 -= childMargins.end;
+      y1 += childMargins.top;
+      y2 -= childMargins.bottom;
+
+      childLayout->Layout( x1, y1, x2, y2 );
+    }
+  }
+}
+
+} // namespace Internal
+} // namespace Toolkit
+} // namespace Dali
diff --git a/dali-toolkit/internal/layouting/grid-impl.h b/dali-toolkit/internal/layouting/grid-impl.h
new file mode 100644 (file)
index 0000000..6afb3f5
--- /dev/null
@@ -0,0 +1,137 @@
+#ifndef DALI_TOOLKIT_INTERNAL_LAYOUTING_GRID_IMPL_H
+#define DALI_TOOLKIT_INTERNAL_LAYOUTING_GRID_IMPL_H
+
+/*
+ * Copyright (c) 2018 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_HEADERS
+#include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/object/base-object.h>
+
+// INTERNAL_HEADERS
+#include <dali-toolkit/devel-api/layouting/layout-group-impl.h>
+#include <dali-toolkit/devel-api/layouting/grid.h>
+#include <dali-toolkit/internal/layouting/grid-locations.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+
+class Grid;
+using GridPtr = IntrusivePtr<Grid>;
+
+class Grid final : public LayoutGroup
+{
+public:
+
+  /**
+   * Creates a pointer to an Internal Grid
+   */
+  static GridPtr New();
+
+  /**
+   * Set grid's the number of columns
+   * @param[in] columns number of columns
+   */
+  void SetNumberOfColumns( int columns );
+
+  /**
+   * Get number of columns, -1 would indicate AUTO_FIT
+   * which means the number has not been set but will be calculated.
+   * @return the number of columns set
+   */
+  int GetNumberOfColumns() const;
+
+  // Movable but not copyable
+  Grid( const Grid& other ) = delete;
+  Grid& operator=( const Grid& other ) = delete;
+  Grid( Grid && ) = default;
+  Grid& operator=( Grid && ) = default;
+
+protected:
+
+  /**
+   * Default Constructor
+   */
+  Grid();
+
+  /**
+   * Destructor
+   */
+  ~Grid();
+
+  /**
+   * @copydoc LayoutItem::OnMeasure
+   */
+  virtual void OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasureSpec ) override;
+
+  /**
+   * @copydoc LayoutItem::OnLayout
+   */
+  virtual void OnLayout( bool changed, LayoutLength l, LayoutLength t, LayoutLength r, LayoutLength b ) override;
+
+private:
+
+  /**
+   * @brief
+   * For the given availableSpace, calculate or retreive the number of required columns.
+   * @param[in] availableSpace the space available for a child in each column.
+   */
+  void DetermineNumberOfColumns( int availableSpace );
+
+private:
+
+  GridLocationsPtr mLocations;
+
+  LayoutLength mTotalHeight;
+  LayoutLength mTotalWidth;
+
+  const int AUTO_FIT = -1;
+
+  int mNumColumns;
+  int mNumRows;
+
+  int mHorizontalSpacing = 0;
+  int mVerticalSpacing = 0;
+  int mRequestedHorizontalSpacing;
+  int mRequestedColumnWidth;
+  int mRequestedNumColumns;
+  int mRequestedNumRows;
+};
+
+} // namespace Internal
+
+inline Internal::Grid& GetImplementation( Dali::Toolkit::Grid& handle )
+{
+  DALI_ASSERT_ALWAYS( handle && "Grid handle is empty" );
+  BaseObject& object = handle.GetBaseObject();
+  return static_cast<Internal::Grid&>( object );
+}
+
+inline const Internal::Grid& GetImplementation( const Dali::Toolkit::Grid& handle )
+{
+  DALI_ASSERT_ALWAYS( handle && "Grid handle is empty" );
+  const BaseObject& object = handle.GetBaseObject();
+  return static_cast<const Internal::Grid&>( object );
+}
+
+} // namespace Toolkit
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_INTERNAL_LAYOUTINGInner
\ No newline at end of file
diff --git a/dali-toolkit/internal/layouting/grid-locations.cpp b/dali-toolkit/internal/layouting/grid-locations.cpp
new file mode 100644 (file)
index 0000000..8cb1cca
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+//CLASS HEADER
+#include <dali-toolkit/internal/layouting/grid-locations.h>
+
+// EXTERNAL HEADERS
+#include <dali/integration-api/debug.h>
+
+// INTERNAL HEADERS
+#include <dali-toolkit/devel-api/layouting/layout-item.h>
+
+namespace
+{
+
+#if defined(DEBUG_ENABLED)
+static Debug::Filter* gLogFilter = Debug::Filter::New( Debug::Concise, false, "LOG_AXIS" );
+#endif
+
+}
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+
+GridLocationsPtr GridLocations::New()
+{
+  GridLocationsPtr gridAxis( new GridLocations() );
+  return gridAxis;
+}
+
+GridLocations::GridLocations()
+: mLocations()
+{
+}
+
+GridLocations::~GridLocations(){}
+
+void GridLocations::CalculateLocations( int numberOfColumns,
+                                        unsigned int availableWidth,
+                                        unsigned int availableHeight,
+                                        unsigned int numberOfCells,
+                                        unsigned int columnWidth,
+                                        unsigned int rowHeight )
+{
+  mLocations.clear();
+
+  // Calculate width and height of columns and rows.
+
+  // Calculate numbers of rows, round down result as later check for remainder.
+  unsigned int numberOfRows = numberOfCells/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;
+
+  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 maxRowHeight = availableHeight / numberOfRows;
+
+  if( rowHeight > 0 )
+  {
+    // Column height supplied so use this unless exceeds available height.
+    rowHeight = std::min( rowHeight, maxRowHeight );
+  }
+  else
+  {
+    // Column height not supplied so use calculated value
+    rowHeight = maxRowHeight;
+  }
+
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "ColumWidth[%d] RowHeight[%d] NumberOfRows[%d] NumberOfColumns[%d]\n",
+                                              columnWidth, rowHeight, numberOfRows, numberOfColumns );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Remainder[%d]\n", numberOfCells%numberOfColumns );
+
+  int  y1 = 0;
+  int  y2 = y1 + rowHeight;
+
+  // Calculate start, end, top and bottom coordinate of each cell.
+
+  // Iterate rows
+  for( auto i = 0u; i < numberOfRows; i++ )
+  {
+    int x1 = 0;
+    int x2 = x1 + columnWidth;
+
+    // Iterate columns
+    for( auto j = 0; j < numberOfColumns; j++ )
+    {
+      GridLocations::Cell cell( x1, x2, y1, y2 );
+      mLocations.push_back( cell );
+      // Calculate starting x and ending x position of each column
+      x1 = x2;
+      x2 = x2 + columnWidth;
+    }
+
+    // Calculate top y and bottom y position of each row.
+    y1 = y2;
+    y2 = y2 + rowHeight;
+  }
+
+#if defined(DEBUG_ENABLED)
+  std::ostringstream oss;
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "GridLocations::CalculateLocations (%d)\n", numberOfCells );
+  for( auto i = 0u; i < numberOfCells; i++ )
+  {
+    DALI_LOG_STREAM( gLogFilter, Debug::Verbose,"x1:"<<mLocations[i].xStart<<" x2:"<<mLocations[i].xEnd<<" y1:"<<mLocations[i].yTop<<" y2:"<<mLocations[i].yBottom);
+  }
+#endif
+}
+
+GridLocations::LocationVector GridLocations::GetLocations()
+{
+#if defined(DEBUG_ENABLED)
+  std::ostringstream oss;
+  auto itemCount = mLocations.size(); // mVerticalLocations mirrors this so same size.
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "GridLocations::GetLocations for %u cells\n", itemCount );
+  for( auto i = 0u; i < itemCount; i++ )
+  {
+    DALI_LOG_STREAM( gLogFilter, Debug::Verbose,"x1:"<<mLocations[i].xStart<<" x2:"<<mLocations[i].xEnd<<" y1:"<<mLocations[i].yTop<<" y2:"<<mLocations[i].yBottom);
+  }
+#endif
+
+  return mLocations;
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+} // namespace Dali
\ No newline at end of file
diff --git a/dali-toolkit/internal/layouting/grid-locations.h b/dali-toolkit/internal/layouting/grid-locations.h
new file mode 100644 (file)
index 0000000..f1f8b6e
--- /dev/null
@@ -0,0 +1,99 @@
+#ifndef DALI_TOOLKIT_INTERNAL_LAYOUTING_GRID_LOCATIONS_H
+#define DALI_TOOLKIT_INTERNAL_LAYOUTING_GRID_LOCATIONS_H
+
+/*
+ * Copyright (c) 2018 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 HEADERS
+#include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/common/dali-vector.h>
+#include <dali/public-api/object/ref-object.h>
+#include <limits.h>
+
+// INTERNAL HEADERS
+#include <dali-toolkit/devel-api/layouting/layout-item-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+
+class GridLocations;
+using GridLocationsPtr = IntrusivePtr<GridLocations>;
+
+/* @brief This internal class houses the algorithm for computing the locations and size of cells.
+ *
+ * A Grid layout uses two instances of this class
+ * distinguished by the "horizontal" flag which is true for the horizontal axis and false
+ * for the vertical one.
+ */
+
+class GridLocations : public RefObject
+{
+
+public:
+
+  static const int UNDEFINED = INT_MIN;
+
+  static const unsigned int HORIZONTAL = 0;
+  static const unsigned int VERTICAL = 1;
+
+  struct Cell
+  {
+    int xStart;
+    int xEnd;
+    int yTop;
+    int yBottom;
+    int explictlyDefined;
+
+    Cell( int x1, int x2, int y1, int y2): xStart(x1), xEnd(x2), yTop(y1), yBottom(y2){};
+  };
+
+  typedef std::vector< Cell > LocationVector;
+
+public:
+
+  static GridLocationsPtr New();
+
+  /*
+   * 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 );
+
+  LocationVector GetLocations();
+
+private:
+
+  GridLocations();
+  ~GridLocations();
+  GridLocations( const GridLocations& other ) = delete;
+  GridLocations& operator=( const GridLocations& other ) = delete;
+
+private:
+
+  LocationVector mLocations;
+
+};
+
+} // namespace Internal
+} // namespace Toolkit
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_INTERNAL_LAYOUTING_GRID_LOCATIONS_H
\ No newline at end of file
index 6027ef7..a787558 100644 (file)
@@ -18,6 +18,9 @@
  *
  */
 
+// EXTERNAL INCLUDES
+#include <dali/devel-api/text-abstraction/font-list.h>
+
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/character-run.h>
 
@@ -35,8 +38,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.
+  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
 };
 
 } // namespace Text
index 7570e04..6ca96ad 100644 (file)
@@ -440,12 +440,18 @@ void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
   FontId previousFontId = 0u;
   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;
 
+    // new description for current character
     TextAbstraction::FontDescription currentFontDescription;
     TextAbstraction::PointSize26Dot6 currentFontPointSize = defaultFontPointSize;
     bool isDefaultFont = true;
@@ -689,9 +695,22 @@ 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 );
+
+    // Developer sets italic to character but selected font cannot support it
+    needSoftwareItalic = ( currentFontDescription.slant == TextAbstraction::FontSlant::ITALIC ) && ( selectedFontDescription.slant < TextAbstraction::FontSlant::ITALIC );
+
     // The font is now validated.
     if( ( fontId != currentFontRun.fontId ) ||
-        isNewParagraphCharacter )
+        isNewParagraphCharacter ||
+        // If font id is same as previous but style is diffrent, initialize new one
+        ( ( fontId == currentFontRun.fontId ) && ( ( needSoftwareBoldening != currentFontRun.softwareBold ) || ( needSoftwareItalic != currentFontRun.softwareItalic ) ) ) )
     {
       // Current run needs to be stored and a new one initialized.
 
@@ -706,6 +725,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;
     }
 
     // Add one more character to the run.
index c6d1f80..2fa2c8b 100644 (file)
@@ -257,6 +257,8 @@ struct AtlasRenderer::Impl
 
         mFontClient.CreateBitmap( glyph.fontId,
                                   glyph.index,
+                                  glyph.softwareItalic,
+                                  glyph.softwareBold,
                                   glyphBufferData,
                                   outline );
 
index c5fa932..0e149d7 100755 (executable)
@@ -672,6 +672,8 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer( const unsigned int bufferWidth
       {
         fontClient.CreateBitmap( glyphInfo->fontId,
                                  glyphInfo->index,
+                                 glyphInfo->softwareItalic,
+                                 glyphInfo->softwareBold,
                                  glyphData.glyphBitmap,
                                  outlineWidth );
       }
index cd0b1d7..624c443 100644 (file)
@@ -137,6 +137,8 @@ void ShapeText( const Vector<Character>& text,
 
     currentFontId = fontRun.fontId;
     currentScript = scriptRun.script;
+    bool softwareItalic = fontRun.softwareItalic;
+    bool softwareBold = fontRun.softwareBold;
 
     // Get the min index to the last character of both runs.
     CharacterIndex currentIndex = min( fontRun.characterRun.characterIndex + fontRun.characterRun.numberOfCharacters,
@@ -170,7 +172,12 @@ void ShapeText( const Vector<Character>& text,
     // Retrieve the glyphs and the glyph to character conversion map.
     Vector<GlyphInfo> tmpGlyphs;
     Vector<CharacterIndex> tmpGlyphToCharacterMap;
-    tmpGlyphs.Resize( numberOfGlyphs );
+
+    GlyphInfo glyphInfo;
+    glyphInfo.softwareItalic = softwareItalic;
+    glyphInfo.softwareBold = softwareBold;
+
+    tmpGlyphs.Resize( numberOfGlyphs, glyphInfo );
     tmpGlyphToCharacterMap.Resize( numberOfGlyphs );
     shaping.GetGlyphs( tmpGlyphs.Begin(),
                        tmpGlyphToCharacterMap.Begin() );
index 53cb7e3..13140a7 100644 (file)
@@ -21,6 +21,7 @@
 // INTERNAL INCLUDES
 #include <dali-toolkit/third-party/nanosvg/nanosvgrast.h>
 #include <dali-toolkit/internal/visuals/svg/svg-visual.h>
+#include <dali/devel-api/adaptor-framework/thread-settings.h>
 
 namespace Dali
 {
@@ -221,6 +222,7 @@ void SvgRasterizeThread::AddCompletedTask( RasterizingTaskPtr task )
 
 void SvgRasterizeThread::Run()
 {
+  SetThreadName( "SVGThread" );
   while( RasterizingTaskPtr task = NextTaskToProcess() )
   {
     task->Rasterize( mRasterizer );
index 783e4e3..7c62965 100644 (file)
@@ -31,7 +31,7 @@ namespace Toolkit
 
 const unsigned int TOOLKIT_MAJOR_VERSION = 1;
 const unsigned int TOOLKIT_MINOR_VERSION = 3;
-const unsigned int TOOLKIT_MICRO_VERSION = 35;
+const unsigned int TOOLKIT_MICRO_VERSION = 36;
 const char * const TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index dea8cbe..1cafb29 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali-toolkit
 Summary:    Dali 3D engine Toolkit
-Version:    1.3.35
+Version:    1.3.36
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT