Merge "atspi: use 'class' key for Dali type name" into devel/master
authorSeoyeon Kim <seoyeon2.kim@samsung.com>
Tue, 11 May 2021 08:23:13 +0000 (08:23 +0000)
committerGerrit Code Review <gerrit@review>
Tue, 11 May 2021 08:23:13 +0000 (08:23 +0000)
47 files changed:
automated-tests/src/dali-shader-generator/CMakeLists.txt
automated-tests/src/dali-shader-generator/tct-dali-shader-generator-core.cpp
automated-tests/src/dali-shader-generator/utc-Dali-ShaderGenerator.cpp [new file with mode: 0644]
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/dali-toolkit-test-utils/toolkit-text-utils.h
automated-tests/src/dali-toolkit-internal/utc-Dali-BidirectionalSupport.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-LogicalModel.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Cursor.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Hyphen-Wrapping.cpp [new file with mode: 0755]
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Layout.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Shaping.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-VisualModel.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp
automated-tests/src/dali-toolkit/utc-Dali-VideoView.cpp
dali-toolkit/devel-api/text/text-enumerations-devel.h
dali-toolkit/devel-api/text/text-utils-devel.cpp
dali-toolkit/internal/controls/video-view/video-view-impl.cpp
dali-toolkit/internal/file.list
dali-toolkit/internal/graphics/shaders/glyphy-common-glsl-shader.def [new file with mode: 0644]
dali-toolkit/internal/graphics/shaders/glyphy-sdf-glsl-shader.def [new file with mode: 0644]
dali-toolkit/internal/graphics/shaders/glyphy-shader-extention-prefix.def [new file with mode: 0644]
dali-toolkit/internal/graphics/shaders/glyphy-shader-fragment-prefix.frag [new file with mode: 0644]
dali-toolkit/internal/graphics/shaders/glyphy-shader-main.frag [new file with mode: 0644]
dali-toolkit/internal/graphics/shaders/glyphy-shader-main.vert [new file with mode: 0644]
dali-toolkit/internal/text/hyphenator.cpp [new file with mode: 0644]
dali-toolkit/internal/text/hyphenator.h [new file with mode: 0644]
dali-toolkit/internal/text/layouts/layout-engine.cpp
dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp
dali-toolkit/internal/text/rendering/text-typesetter.cpp
dali-toolkit/internal/text/rendering/vector-based/glyphy-shader/glyphy-common-glsl.h [deleted file]
dali-toolkit/internal/text/rendering/vector-based/glyphy-shader/glyphy-sdf-glsl.h [deleted file]
dali-toolkit/internal/text/rendering/vector-based/glyphy-shader/glyphy-shader.cpp
dali-toolkit/internal/text/rendering/view-model.cpp
dali-toolkit/internal/text/rendering/view-model.h
dali-toolkit/internal/text/text-controller-impl.cpp
dali-toolkit/internal/text/text-controller.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
dali-toolkit/internal/text/text-view.cpp
dali-toolkit/internal/text/text-view.h
dali-toolkit/internal/text/visual-model-impl.h
dali-toolkit/public-api/dali-toolkit-version.cpp
packaging/dali-toolkit.spec

index 7057a36..9a30ca7 100644 (file)
 SET(PKG_NAME "dali-shader-generator")
 
 SET(EXEC_NAME "tct-${PKG_NAME}-core")
+SET(EXEC_NAME "tct-${PKG_NAME}-core")
+
+SET(CAPI_LIB "dali-shader-generator")
 
-PKG_CHECK_MODULES(${EXEC_NAME} REQUIRED
+PKG_CHECK_MODULES(${CAPI_LIB} REQUIRED
+  dali2-core
+  dali2-adaptor
   dali2-toolkit
 )
 
-ADD_EXECUTABLE(${EXEC_NAME} ${EXEC_NAME}.cpp)
+SET(TC_SOURCES
+  utc-Dali-ShaderGenerator.cpp
+)
+
+# List of test harness files (Won't get parsed for test cases)
+SET(TEST_HARNESS_DIR "../dali-toolkit/dali-toolkit-test-utils")
+
+SET(TEST_HARNESS_SOURCES
+  ${TEST_HARNESS_DIR}/toolkit-adaptor.cpp
+  ${TEST_HARNESS_DIR}/toolkit-application.cpp
+  ${TEST_HARNESS_DIR}/toolkit-event-thread-callback.cpp
+  ${TEST_HARNESS_DIR}/toolkit-environment-variable.cpp
+  ${TEST_HARNESS_DIR}/toolkit-input-method-context.cpp
+  ${TEST_HARNESS_DIR}/toolkit-input-method-options.cpp
+  ${TEST_HARNESS_DIR}/toolkit-lifecycle-controller.cpp
+  ${TEST_HARNESS_DIR}/toolkit-orientation.cpp
+  ${TEST_HARNESS_DIR}/toolkit-style-monitor.cpp
+  ${TEST_HARNESS_DIR}/toolkit-test-application.cpp
+  ${TEST_HARNESS_DIR}/toolkit-timer.cpp
+  ${TEST_HARNESS_DIR}/toolkit-trigger-event-factory.cpp
+  ${TEST_HARNESS_DIR}/toolkit-window.cpp
+  ${TEST_HARNESS_DIR}/toolkit-scene-holder.cpp
+  ${TEST_HARNESS_DIR}/dali-test-suite-utils.cpp
+  ${TEST_HARNESS_DIR}/dali-toolkit-test-suite-utils.cpp
+  ${TEST_HARNESS_DIR}/dummy-control.cpp
+  ${TEST_HARNESS_DIR}/mesh-builder.cpp
+  ${TEST_HARNESS_DIR}/test-actor-utils.cpp
+  ${TEST_HARNESS_DIR}/test-animation-data.cpp
+  ${TEST_HARNESS_DIR}/test-application.cpp
+  ${TEST_HARNESS_DIR}/test-button.cpp
+  ${TEST_HARNESS_DIR}/test-harness.cpp
+  ${TEST_HARNESS_DIR}/test-gesture-generator.cpp
+  ${TEST_HARNESS_DIR}/test-gl-abstraction.cpp
+  ${TEST_HARNESS_DIR}/test-gl-sync-abstraction.cpp
+  ${TEST_HARNESS_DIR}/test-graphics-buffer.cpp
+  ${TEST_HARNESS_DIR}/test-graphics-command-buffer.cpp
+  ${TEST_HARNESS_DIR}/test-graphics-controller.cpp
+  ${TEST_HARNESS_DIR}/test-graphics-texture.cpp
+  ${TEST_HARNESS_DIR}/test-graphics-sampler.cpp
+  ${TEST_HARNESS_DIR}/test-graphics-program.cpp
+  ${TEST_HARNESS_DIR}/test-graphics-pipeline.cpp
+  ${TEST_HARNESS_DIR}/test-graphics-shader.cpp
+  ${TEST_HARNESS_DIR}/test-graphics-reflection.cpp
+  ${TEST_HARNESS_DIR}/test-platform-abstraction.cpp
+  ${TEST_HARNESS_DIR}/test-render-controller.cpp
+  ${TEST_HARNESS_DIR}/test-trace-call-stack.cpp
+)
+
+ADD_DEFINITIONS(-DTEST_RESOURCE_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}/../../resources\" )
+
+FOREACH(directory ${${CAPI_LIB}_LIBRARY_DIRS})
+    SET(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -L${directory}")
+ENDFOREACH(directory ${CAPI_LIB_LIBRARY_DIRS})
+
+INCLUDE_DIRECTORIES(
+  ../../../
+  ${${CAPI_LIB}_INCLUDE_DIRS}
+  ../dali-toolkit/dali-toolkit-test-utils
+)
+
+ADD_COMPILE_OPTIONS( -O0 -ggdb --coverage -Wall -Werror -DDEBUG_ENABLED)
+ADD_COMPILE_OPTIONS( ${${CAPI_LIB}_CFLAGS_OTHER} )
+
+ADD_EXECUTABLE(${EXEC_NAME} ${EXEC_NAME}.h ${EXEC_NAME}.cpp ${TC_SOURCES} ${TEST_HARNESS_SOURCES})
+
+TARGET_LINK_LIBRARIES(${EXEC_NAME}
+  ${${CAPI_LIB}_LIBRARIES}
+  -lpthread --coverage
+)
+
+ADD_CUSTOM_COMMAND(
+  COMMAND ${SCRIPT_DIR}/tcheadgen.sh ${EXEC_NAME}.h ${TC_SOURCES}
+  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+  OUTPUT ${EXEC_NAME}.h
+  COMMENT "Generating test tables"
+)
 
 INSTALL(PROGRAMS ${EXEC_NAME}
-    DESTINATION ${BIN_DIR}/${EXEC_NAME}
+  DESTINATION ${BIN_DIR}/${EXEC_NAME}
 )
 
 SET(SHADER_GENERATOR dali-shader-generator)
 SET(GENERATED_FOLDER ${CMAKE_CURRENT_BINARY_DIR}/shader/generated)
 SET(SHADER_FOLDER ${CMAKE_CURRENT_SOURCE_DIR}/shader)
 
+# All the shader generator execution tests are below
+
 ADD_CUSTOM_TARGET(test_help ALL COMMAND ${SHADER_GENERATOR} -h | grep "DALi Shader Generator" > /dev/null 2>&1 && echo "test_help Succeeded" VERBATIM)
 ADD_CUSTOM_TARGET(test_no_params ALL COMMAND ${SHADER_GENERATOR} > /dev/null 2>&1 || echo "test_no_params Succeeded" VERBATIM)
 ADD_CUSTOM_TARGET(test_version ALL COMMAND ${SHADER_GENERATOR} -v | wc -l | grep 1 > /dev/null 2>&1 && echo "test_version Succeeded" VERBATIM)
@@ -47,3 +129,4 @@ ADD_CUSTOM_TARGET(
   ALL
   COMMAND ${SHADER_GENERATOR} ${SHADER_FOLDER} ${GENERATED_FOLDER} | grep "SHADER_SHADER_DEFINE_DEF" | grep "shader-define-def.h" > /dev/null 2>&1 && echo "test_def_correct Succeeded"
   VERBATIM)
+
index 842fd98..539d80c 100644 (file)
@@ -1,6 +1,7 @@
-#include <iostream>
+#include <test-harness.h>
+#include "tct-dali-shader-generator-core.h"
+
 int main(int argc, char * const argv[])
 {
-  std::cout << "All tests run as part of Cmake build." << std::endl;
-  return 0;
+  return TestHarness::RunTests(argc, argv, tc_array);
 }
diff --git a/automated-tests/src/dali-shader-generator/utc-Dali-ShaderGenerator.cpp b/automated-tests/src/dali-shader-generator/utc-Dali-ShaderGenerator.cpp
new file mode 100644 (file)
index 0000000..68fc2ab
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2021 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>
+
+void utc_dali_shader_generator_startup(void)
+{
+  test_return_value = TET_UNDEF;
+}
+
+void utc_dali_shader_generator_cleanup(void)
+{
+  test_return_value = TET_PASS;
+}
+
+int UtcDaliShaderGenerator(void)
+{
+  tet_infoline("All tests run as part of cmake build");
+  DALI_TEST_CHECK(true);
+  END_TEST;
+}
index 1162266..f20e494 100755 (executable)
@@ -36,6 +36,7 @@ SET(TC_SOURCES
  utc-Dali-Visuals-internal.cpp
  utc-Dali-VisualModel.cpp
  utc-Dali-VisualUrl.cpp
+ utc-Dali-Text-Hyphen-Wrapping.cpp
 )
 
 IF(ELDBUS_AVAILABLE)
index 1e745b1..0a426b0 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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.
@@ -32,6 +32,7 @@
 #include <dali-toolkit/internal/text/shaper.h>
 #include <dali-toolkit/internal/text/text-controller-impl.h>
 #include <dali-toolkit/internal/text/markup-processor.h>
+#include <dali-toolkit/internal/text/hyphenator.h>
 
 namespace Dali
 {
@@ -100,7 +101,8 @@ void CreateTextModel( const std::string& text,
                       Size& layoutSize,
                       ModelPtr& textModel,
                       MetricsPtr& metrics,
-                      bool markupProcessorEnabled )
+                      bool markupProcessorEnabled,
+                      LineWrap::Mode wrapMode )
 {
   textModel = Model::New(); ///< Pointer to the text's model.
   LogicalModelPtr logicalModel = textModel->mLogicalModel;
@@ -154,6 +156,41 @@ void CreateTextModel( const std::string& text,
     return;
   }
 
+  textModel->mLineWrapMode = wrapMode;
+
+  if(textModel->mLineWrapMode == ((Text::LineWrap::Mode)DevelText::LineWrap::HYPHENATION) ||
+       textModel->mLineWrapMode == ((Text::LineWrap::Mode)DevelText::LineWrap::MIXED))
+  {
+    CharacterIndex end                 = characterCount;
+    LineBreakInfo* lineBreakInfoBuffer = lineBreakInfo.Begin();
+
+    for(CharacterIndex index = 0; index < end; index++)
+    {
+      CharacterIndex wordEnd = index;
+      while((*(lineBreakInfoBuffer + wordEnd) != TextAbstraction::LINE_ALLOW_BREAK) && (*(lineBreakInfoBuffer + wordEnd) != TextAbstraction::LINE_MUST_BREAK))
+      {
+        wordEnd++;
+      }
+
+      if((wordEnd + 1) == end) // add last char
+      {
+        wordEnd++;
+      }
+
+      Vector<bool> hyphens = GetWordHyphens(utf32Characters.Begin() + index, wordEnd - index, nullptr);
+
+      for(CharacterIndex i = 0; i < (wordEnd - index); i++)
+      {
+        if(hyphens[i])
+        {
+          *(lineBreakInfoBuffer + index + i) = TextAbstraction::LINE_HYPHENATION_BREAK;
+        }
+      }
+
+      index = wordEnd;
+    }
+  }
+
   // 3) Set the script info.
   MultilanguageSupport multilanguageSupport = MultilanguageSupport::Get();
 
@@ -284,7 +321,6 @@ void CreateTextModel( const std::string& text,
 
   // Set the layout parameters.
   textModel->mHorizontalAlignment = Text::HorizontalAlignment::BEGIN;
-  textModel->mLineWrapMode = LineWrap::WORD;
   textModel->mIgnoreSpacesAfterText = true;
   textModel->mMatchSystemLanguageDirection = false;
   Layout::Parameters layoutParameters( textArea,
index eb0dd40..6e30bbb 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_TEXT_UTILS_H
 
 /*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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.
@@ -64,7 +64,8 @@ void CreateTextModel( const std::string& text,
                       Size& layoutSize,
                       ModelPtr& textModel,
                       MetricsPtr& metrics,
-                      bool markupProcessorEnabled );
+                      bool markupProcessorEnabled,
+                      LineWrap::Mode wrapMode );
 
 /**
  * @brief Configures the text @p controller similarly to the one configured by the text-label.
index e056f73..de772f3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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,7 +111,8 @@ bool SetBidirectionalInfoTest( const SetBidirectionalInfoData& data )
                    layoutSize,
                    textModel,
                    metrics,
-                   false );
+                   false,
+                   LineWrap::WORD );
 
   LogicalModelPtr logicalModel = textModel->mLogicalModel;
   VisualModelPtr visualModel = textModel->mVisualModel;
@@ -196,7 +197,8 @@ bool GetMirroredTextTest( const GetMirroredTextData& data )
                    layoutSize,
                    textModel,
                    metrics,
-                   false );
+                   false,
+                   LineWrap::WORD );
 
   LogicalModelPtr logicalModel = textModel->mLogicalModel;
   VisualModelPtr visualModel = textModel->mVisualModel;
@@ -272,7 +274,8 @@ bool GetCharactersDirectionTest( const GetCharactersDirectionData& data )
                    layoutSize,
                    textModel,
                    metrics,
-                   data.markupProcessorEnabled );
+                   data.markupProcessorEnabled,
+                   LineWrap::WORD );
 
   LogicalModelPtr logicalModel = textModel->mLogicalModel;
   VisualModelPtr visualModel = textModel->mVisualModel;
index 7cbbe90..8515172 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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.
@@ -118,7 +118,8 @@ bool CreateParagraphTest( const CreateParagraphData& data )
                    layoutSize,
                    textModel,
                    metrics,
-                   false );
+                   false,
+                   LineWrap::WORD );
 
   LogicalModelPtr logicalModel = textModel->mLogicalModel;
   VisualModelPtr visualModel = textModel->mVisualModel;
@@ -180,7 +181,8 @@ bool FindParagraphTest( const FindParagraphData& data )
                    layoutSize,
                    textModel,
                    metrics,
-                   false );
+                   false,
+                   LineWrap::WORD );
 
   LogicalModelPtr logicalModel = textModel->mLogicalModel;
   VisualModelPtr visualModel = textModel->mVisualModel;
@@ -231,7 +233,8 @@ bool FetchBidirectionalLineInfoTest( const FetchBidirectionalLineInfoData& data
                    layoutSize,
                    textModel,
                    metrics,
-                   false );
+                   false,
+                   LineWrap::WORD );
 
   LogicalModelPtr logicalModel = textModel->mLogicalModel;
   VisualModelPtr visualModel = textModel->mVisualModel;
@@ -277,7 +280,8 @@ bool GetLogicalCharacterIndexTest( const GetLogicalCharacterIndexData& data )
                    layoutSize,
                    textModel,
                    metrics,
-                   false );
+                   false,
+                   LineWrap::WORD );
 
   LogicalModelPtr logicalModel = textModel->mLogicalModel;
   VisualModelPtr visualModel = textModel->mVisualModel;
@@ -340,7 +344,8 @@ bool GetLogicalCursorIndexTest( const GetLogicalCursorIndexData& data )
                    layoutSize,
                    textModel,
                    metrics,
-                   false );
+                   false,
+                   LineWrap::WORD );
 
   LogicalModelPtr logicalModel = textModel->mLogicalModel;
   VisualModelPtr visualModel = textModel->mVisualModel;
index 2ab84e7..78d7cf8 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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,7 +111,8 @@ bool GetClosestLineTest( const GetClosestLineData& data )
                    layoutSize,
                    textModel,
                    metrics,
-                   false );
+                   false,
+                   LineWrap::WORD );
 
   LogicalModelPtr logicalModel = textModel->mLogicalModel;
   VisualModelPtr visualModel = textModel->mVisualModel;
@@ -157,7 +158,8 @@ bool GetClosestCursorIndexTest( const GetClosestCursorIndexData& data )
                    layoutSize,
                    textModel,
                    metrics,
-                   false );
+                   false,
+                   LineWrap::WORD );
 
   LogicalModelPtr logicalModel = textModel->mLogicalModel;
   VisualModelPtr visualModel = textModel->mVisualModel;
@@ -207,7 +209,8 @@ bool GetCursorPositionTest( const GetCursorPositionData& data )
                    layoutSize,
                    textModel,
                    metrics,
-                   false );
+                   false,
+                   LineWrap::WORD );
 
   LogicalModelPtr logicalModel = textModel->mLogicalModel;
   VisualModelPtr visualModel = textModel->mVisualModel;
@@ -260,7 +263,8 @@ bool FindSelectionIndicesTest( const FindSelectionIndicesData& data )
                    layoutSize,
                    textModel,
                    metrics,
-                   false );
+                   false,
+                   LineWrap::WORD );
 
   LogicalModelPtr logicalModel = textModel->mLogicalModel;
   VisualModelPtr visualModel = textModel->mVisualModel;
diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Hyphen-Wrapping.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Hyphen-Wrapping.cpp
new file mode 100755 (executable)
index 0000000..ccc8463
--- /dev/null
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 2021 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 <unistd.h>
+
+#include <dali-toolkit/internal/text/layouts/layout-engine.h>
+#include <dali-toolkit/internal/text/layouts/layout-parameters.h>
+#include <dali-toolkit/internal/text/text-run-container.h>
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <toolkit-text-utils.h>
+
+using namespace Dali;
+using namespace Toolkit;
+using namespace Text;
+
+
+namespace
+{
+
+const std::string DEFAULT_FONT_DIR( "/resources/fonts" );
+
+struct LayoutTextData
+{
+  std::string          text;
+  Size                 textArea;
+  unsigned int         numberOfFonts;
+  FontDescriptionRun  *fontDescriptions;
+  unsigned int         numberOfLines;
+  LineRun*             lines;
+  Layout::Engine::Type layout;
+  unsigned int         startIndex;
+  unsigned int         numberOfGlyphs;
+  Text::LineWrap::Mode wrapMode;
+};
+
+void Print( const LineRun& line )
+{
+  std::cout << "        glyph run, index : " << line.glyphRun.glyphIndex << ", num glyphs : " << line.glyphRun.numberOfGlyphs << std::endl;
+  std::cout << "    character run, index : " << line.characterRun.characterIndex << ", num chars : " << line.characterRun.numberOfCharacters << std::endl;
+}
+
+bool LayoutTextTest( const LayoutTextData& data )
+{
+  // Load some fonts.
+  TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
+  fontClient.SetDpi( 96u, 96u );
+
+  char* pathNamePtr = get_current_dir_name();
+  const std::string pathName( pathNamePtr );
+  free( pathNamePtr );
+
+  fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansRegular.ttf" );
+
+  // 1) Create the model.
+  ModelPtr textModel;
+  MetricsPtr metrics;
+  Size layoutSize;
+
+  Vector<FontDescriptionRun> fontDescriptionRuns;
+  if( 0u != data.numberOfFonts )
+  {
+    fontDescriptionRuns.Insert( fontDescriptionRuns.End(),
+                                data.fontDescriptions,
+                                data.fontDescriptions + data.numberOfFonts );
+  }
+
+  LayoutOptions options;
+  options.align = false;
+  CreateTextModel( data.text,
+                   data.textArea,
+                   fontDescriptionRuns,
+                   options,
+                   layoutSize,
+                   textModel,
+                   metrics,
+                   false,
+                   data.wrapMode );
+
+  Vector<LineRun>& lines = textModel->mVisualModel->mLines;
+
+  // 4) Compare the results.
+
+  if( lines.Count() != data.numberOfLines )
+  {
+    std::cout << "  Different number of lines : " << lines.Count() << ", expected : " << data.numberOfLines << std::endl;
+    return false;
+  }
+
+  for( unsigned int index = 0u; index < data.numberOfLines; ++index )
+  {
+    const LineRun& line = *( lines.Begin() + index );
+    const LineRun& expectedLine = *( data.lines + index );
+
+    if( line.characterRun.characterIndex != expectedLine.characterRun.characterIndex )
+    {
+      std::cout << "  Different line info for line : " << index << std::endl;
+      Print( line );
+      std::cout << "  expected" << std::endl;
+      Print( expectedLine );
+      return false;
+    }
+    if( line.characterRun.numberOfCharacters != expectedLine.characterRun.numberOfCharacters )
+    {
+      std::cout << "  Different line info for line : " << index << std::endl;
+      Print( line );
+      std::cout << "  expected" << std::endl;
+      Print( expectedLine );
+      return false;
+    }
+  }
+
+  return true;
+}
+
+} // namespace
+
+
+int UtcDaliTextHyphenWrapping(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextHyphenWrapping");
+
+  // Layout some lines of left to right text.
+
+  const std::string fontFamily( "TizenSans" );
+
+  // Set a known font description
+  FontDescriptionRun fontDescriptionRun1;
+  fontDescriptionRun1.characterRun.characterIndex = 0u;
+  fontDescriptionRun1.characterRun.numberOfCharacters = 13u;
+  fontDescriptionRun1.familyLength = fontFamily.size();
+  fontDescriptionRun1.familyName = new char[fontDescriptionRun1.familyLength];
+  memcpy( fontDescriptionRun1.familyName, fontFamily.c_str(), fontDescriptionRun1.familyLength );
+  fontDescriptionRun1.familyDefined = true;
+  fontDescriptionRun1.weightDefined = false;
+  fontDescriptionRun1.widthDefined = false;
+  fontDescriptionRun1.slantDefined = false;
+  fontDescriptionRun1.sizeDefined = false;
+
+  Vector<FontDescriptionRun> fontDescriptionRuns;
+  fontDescriptionRuns.PushBack( fontDescriptionRun1 );
+  Size textArea(65.0f, 200.f);
+  
+  LineRun line1 =
+  {
+    { 0u, 5u },
+    { 0u, 5u },
+    0.f,
+    0.f,
+    0.f,
+    0.f,
+    0.f,
+    0.f,
+    false,
+    false
+  };
+  LineRun line2 =
+  {
+    { 5u, 8u },
+    { 5u, 8u },
+    0.f,
+    0.f,
+    0.f,
+    0.f,
+    0.f,
+    0.f,
+    false,
+    false
+  };
+  
+  Vector<LineRun> lines;
+  lines.PushBack( line1 );
+  lines.PushBack( line2 );
+
+  LayoutTextData data =
+  {
+    "Hi Experiment",
+    textArea,
+    1u,
+    fontDescriptionRuns.Begin(),
+    2u,
+    lines.Begin(),
+    Layout::Engine::MULTI_LINE_BOX,
+    0u,
+    13u,
+    (Text::LineWrap::Mode)DevelText::LineWrap::HYPHENATION
+  };
+
+  if( !LayoutTextTest( data ) )
+  {
+    tet_result(TET_FAIL);
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextMixedWrapping(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextMixedWrapping");
+
+  // Layout some lines of left to right text.
+
+  const std::string fontFamily( "DejaVuSans" );
+
+  // Set a known font description
+  FontDescriptionRun fontDescriptionRun1;
+  fontDescriptionRun1.characterRun.characterIndex = 0u;
+  fontDescriptionRun1.characterRun.numberOfCharacters = 13u;
+  fontDescriptionRun1.familyLength = fontFamily.size();
+  fontDescriptionRun1.familyName = new char[fontDescriptionRun1.familyLength];
+  memcpy( fontDescriptionRun1.familyName, fontFamily.c_str(), fontDescriptionRun1.familyLength );
+  fontDescriptionRun1.familyDefined = true;
+  fontDescriptionRun1.weightDefined = false;
+  fontDescriptionRun1.widthDefined = false;
+  fontDescriptionRun1.slantDefined = false;
+  fontDescriptionRun1.sizeDefined = false;
+
+  Vector<FontDescriptionRun> fontDescriptionRuns;
+  fontDescriptionRuns.PushBack( fontDescriptionRun1 );
+  Size textArea(72.0f, 200.f);
+  
+  LineRun line1 =
+  {
+    { 0u, 3u },
+    { 0u, 3u },
+    0.f,
+    0.f,
+    0.f,
+    0.f,
+    0.f,
+    0.f,
+    false,
+    false
+  };
+  LineRun line2 =
+  {
+    { 3u, 6u },
+    { 3u, 6u },
+    0.f,
+    0.f,
+    0.f,
+    0.f,
+    0.f,
+    0.f,
+    false,
+    false
+  };
+  LineRun line3 =
+  {
+    { 9u, 4u },
+    { 9u, 4u },
+    0.f,
+    0.f,
+    0.f,
+    0.f,
+    0.f,
+    0.f,
+    false,
+    false
+  };
+  
+  Vector<LineRun> lines;
+  lines.PushBack( line1 );
+  lines.PushBack( line2 );
+  lines.PushBack( line3 );
+
+  LayoutTextData data =
+  {
+    "Hi Experiment",
+    textArea,
+    1u,
+    fontDescriptionRuns.Begin(),
+    3u,
+    lines.Begin(),
+    Layout::Engine::MULTI_LINE_BOX,
+    0u,
+    13u,
+    (Text::LineWrap::Mode)DevelText::LineWrap::MIXED
+  };
+
+  if( !LayoutTextTest( data ) )
+  {
+    tet_result(TET_FAIL);
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
\ No newline at end of file
index 05226d4..8bdecaa 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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.
@@ -108,7 +108,8 @@ bool LayoutTextTest( const LayoutTextData& data )
                    layoutSize,
                    textModel,
                    metrics,
-                   false );
+                   false,
+                   LineWrap::WORD );
 
   LogicalModelPtr logicalModel = textModel->mLogicalModel;
   VisualModelPtr visualModel = textModel->mVisualModel;
@@ -363,7 +364,8 @@ bool AlignTest( const AlignData& data )
                    layoutSize,
                    textModel,
                    metrics,
-                   false );
+                   false,
+                   LineWrap::WORD );
 
   LogicalModelPtr logicalModel = textModel->mLogicalModel;
   VisualModelPtr visualModel = textModel->mVisualModel;
index a7534f9..52c8808 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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.
@@ -140,7 +140,8 @@ bool ShapeInfoTest( const ShapeInfoData& data )
                    layoutSize,
                    textModel,
                    metrics,
-                   false );
+                   false,
+                   LineWrap::WORD );
 
   LogicalModelPtr logicalModel = textModel->mLogicalModel;
   VisualModelPtr visualModel = textModel->mVisualModel;
index df247e0..43157ff 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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,7 +79,8 @@ bool SetGlyphsPerCharacterTest( const SetGlyphsPerCharacterData& data )
                    layoutSize,
                    textModel,
                    metrics,
-                   false );
+                   false,
+                   LineWrap::WORD );
 
   LogicalModelPtr logicalModel = textModel->mLogicalModel;
   VisualModelPtr visualModel = textModel->mVisualModel;
@@ -163,7 +164,8 @@ bool SetCharacterToGlyphTest( const SetCharacterToGlyphData& data )
                    layoutSize,
                    textModel,
                    metrics,
-                   false );
+                   false,
+                   LineWrap::WORD );
 
   LogicalModelPtr logicalModel = textModel->mLogicalModel;
   VisualModelPtr visualModel = textModel->mVisualModel;
index 3bd9ee6..626432e 100644 (file)
@@ -28,6 +28,7 @@
 #include <dali-toolkit/dali-toolkit.h>
 #include <dali-toolkit/devel-api/controls/text-controls/text-editor-devel.h>
 #include <dali-toolkit/devel-api/text/rendering-backend.h>
+#include <dali-toolkit/devel-api/text/text-enumerations-devel.h>
 
 using namespace Dali;
 using namespace Toolkit;
@@ -3640,4 +3641,52 @@ int UtcDaliTextEditorAtlasLimitationIsEnabledPerformanceCases(void)
   }
 
   END_TEST;
+}
+
+int UtcDaliTextEditorHyphenWrapMode(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextEditorHyphenWrapMode ");
+
+  int lineCount =0;
+  TextEditor textEditor = TextEditor::New();
+
+  textEditor.SetProperty( Actor::Property::SIZE, Vector2( 150.0f, 300.f ) );
+
+  application.GetScene().Add( textEditor );
+  application.SendNotification();
+  application.Render();
+
+  textEditor.SetProperty( TextEditor::Property::TEXT, "Hi Experimen" );
+  textEditor.SetProperty(TextEditor::Property::LINE_WRAP_MODE, DevelText::LineWrap::HYPHENATION);
+  DALI_TEST_EQUALS( textEditor.GetProperty< int >( TextEditor::Property::LINE_WRAP_MODE ), static_cast< int >( DevelText::LineWrap::HYPHENATION ), TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  lineCount = textEditor.GetProperty<int>( TextEditor::Property::LINE_COUNT );
+  /*
+    text will be :
+    Hi Exp-
+    erimen
+  */
+  DALI_TEST_EQUALS( lineCount, 2, TEST_LOCATION );
+
+  textEditor.SetProperty( TextEditor::Property::TEXT, "Hi Experimen" );
+  textEditor.SetProperty(TextEditor::Property::LINE_WRAP_MODE, DevelText::LineWrap::MIXED);
+  DALI_TEST_EQUALS( textEditor.GetProperty< int >( TextEditor::Property::LINE_WRAP_MODE ), static_cast< int >( DevelText::LineWrap::MIXED ), TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  lineCount = textEditor.GetProperty<int>( TextEditor::Property::LINE_COUNT );
+  /*
+    text will be :
+    Hi
+    Experi-
+    men
+  */
+  DALI_TEST_EQUALS( lineCount, 3, TEST_LOCATION );
+
+  END_TEST;
 }
\ No newline at end of file
index d8a7c18..ac7403b 100644 (file)
@@ -1836,4 +1836,52 @@ int UtcDaliTextLabelAtlasLimitationIsEnabledForLargeFontPointSize(void)
   DALI_TEST_GREATER( lessThanHeight, static_cast<uint32_t>(naturalSize.height), TEST_LOCATION );
 
   END_TEST;
-}
\ No newline at end of file
+}
+
+int UtcDaliTextLabelHyphenWrapMode(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextLabelHyphenWrapMode ");
+
+  int lineCount =0;
+  TextLabel label = TextLabel::New();
+  label.SetProperty( Actor::Property::SIZE, Vector2( 150.0f, 300.f ));
+  label.SetProperty( TextLabel::Property::POINT_SIZE, 12.f );
+  label.SetProperty( TextLabel::Property::MULTI_LINE, true);
+  application.GetScene().Add( label );
+  application.SendNotification();
+  application.Render();
+
+  label.SetProperty( TextLabel::Property::TEXT, "Hi Experimen" );
+  label.SetProperty(TextLabel::Property::LINE_WRAP_MODE,DevelText::LineWrap::HYPHENATION);
+  DALI_TEST_EQUALS( label.GetProperty< int >( TextLabel::Property::LINE_WRAP_MODE ), static_cast< int >( DevelText::LineWrap::HYPHENATION ), TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  lineCount = label.GetProperty<int>( TextLabel::Property::LINE_COUNT );
+  /*
+    text will be :
+    Hi Exp-
+    erimen
+  */
+  DALI_TEST_EQUALS( lineCount, 2, TEST_LOCATION );
+
+  label.SetProperty( TextLabel::Property::TEXT, "Hi Experimen" );
+  label.SetProperty(TextLabel::Property::LINE_WRAP_MODE,DevelText::LineWrap::MIXED);
+  DALI_TEST_EQUALS( label.GetProperty< int >( TextLabel::Property::LINE_WRAP_MODE ), static_cast< int >( DevelText::LineWrap::MIXED ), TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  lineCount = label.GetProperty<int>( TextLabel::Property::LINE_COUNT );
+  /*
+    text will be :
+    Hi
+    Experi-
+    men
+  */
+  DALI_TEST_EQUALS( lineCount, 3, TEST_LOCATION );
+
+  END_TEST;
+}
index 9a77bba..de842bf 100644 (file)
@@ -458,6 +458,36 @@ int UtcDaliVideoViewMethodsForCoverage2(void)
   END_TEST;
 }
 
+int UtcDaliVideoViewCustomShaderForCoverage3(void)
+{
+  ToolkitTestApplication application;
+  VideoView videoView = VideoView::New();
+  DALI_TEST_CHECK( videoView );
+
+  ToolkitApplication::DECODED_IMAGES_SUPPORTED = true;
+
+  videoView.SetProperty( Toolkit::VideoView::Property::UNDERLAY, false );
+  bool isUnderlay = videoView.GetProperty( Toolkit::VideoView::Property::UNDERLAY ).Get< bool >();
+  DALI_TEST_CHECK( !isUnderlay );
+
+  application.GetScene().Add( videoView );
+  videoView.SetProperty( VideoView::Property::VIDEO, "testvideo" );
+
+  Property::Map customShader;
+  customShader.Insert( "vertexShader", VERTEX_SHADER );
+
+  Property::Map map;
+  map.Insert( "shader", customShader );
+
+  videoView.SetProperty( VideoView::Property::VIDEO, map );
+
+  Property::Map map2;
+  Property::Value value = videoView.GetProperty( VideoView::Property::VIDEO );
+
+  DALI_TEST_CHECK( !value.Get( map2 ) );
+  END_TEST;
+}
+
 int UtcDaliVideoViewPropertyUnderlay(void)
 {
   ToolkitTestApplication application;
index 0163cc6..a74af43 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_TEXT_ENUMERATIONS_DEVEL_H
 
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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,6 +44,17 @@ enum Type
 };
 
 } // namespace VerticalLineAlignment
+namespace LineWrap
+{
+enum Mode
+{
+  WORD,
+  CHARACTER,
+  HYPHENATION, // HYPHENATION mode will add hyphen and move part of the word to the next line.
+  MIXED        // MIXEd mode will apply WORD mode, if failed try HYPHENATION mode, if failed try CHARACTER.
+};
+
+} // namespace LineWrap
 
 } // namespace DevelText
 
index 787cc0f..a4dbce4 100644 (file)
@@ -1030,7 +1030,7 @@ Size LayoutText(const RendererParameters& textParameters, TextAbstraction::TextR
   // Resize the vector of positions to have the same size than the vector of glyphs.
   rendererParameters.positions.Resize(numberOfGlyphs);
 
-  textModel->mLineWrapMode                 = LineWrap::WORD;
+  textModel->mLineWrapMode                 = Text::LineWrap::WORD;
   textModel->mIgnoreSpacesAfterText        = false;
   textModel->mMatchSystemLanguageDirection = false;
   Text::Layout::Parameters layoutParameters(internalDataModel.textLayoutArea,
index 85b219e..509426e 100644 (file)
@@ -27,6 +27,7 @@
 #include <dali/public-api/animation/constraint.h>
 #include <dali/public-api/object/type-registry-helper.h>
 #include <dali/public-api/object/type-registry.h>
+#include <dali/devel-api/rendering/texture-devel.h>
 #include <cstring>
 
 // INTERNAL INCLUDES
@@ -869,7 +870,7 @@ void VideoView::PlayAnimation(Dali::Animation animation)
 
 Dali::Shader VideoView::CreateShader()
 {
-  std::string fragmentShader = "#extension GL_OES_EGL_image_external:require\n";
+  std::string fragmentShader;
   std::string vertexShader;
   std::string customFragmentShader;
   bool        checkShader = false;
@@ -900,13 +901,15 @@ Dali::Shader VideoView::CreateShader()
 
     if(!fragmentShaderValue || !checkShader)
     {
-      fragmentShader += SHADER_VIDEO_VIEW_TEXTURE_FRAG.data();
+      fragmentShader = SHADER_VIDEO_VIEW_TEXTURE_FRAG.data();
+      DevelTexture::ApplyNativeFragmentShader(mNativeTexture, fragmentShader);
     }
   }
   else
   {
-    vertexShader = SHADER_VIDEO_VIEW_TEXTURE_VERT.data();
-    fragmentShader += SHADER_VIDEO_VIEW_TEXTURE_FRAG.data();
+    vertexShader   = SHADER_VIDEO_VIEW_TEXTURE_VERT.data();
+    fragmentShader = SHADER_VIDEO_VIEW_TEXTURE_FRAG.data();
+    DevelTexture::ApplyNativeFragmentShader(mNativeTexture, fragmentShader);
   }
 
   return Dali::Shader::New(vertexShader, fragmentShader);
index 35ac87b..395dfc8 100644 (file)
@@ -142,6 +142,7 @@ SET( toolkit_src_files
    ${toolkit_src_dir}/text/property-string-parser.cpp
    ${toolkit_src_dir}/text/segmentation.cpp
    ${toolkit_src_dir}/text/shaper.cpp
+   ${toolkit_src_dir}/text/hyphenator.cpp
    ${toolkit_src_dir}/text/text-enumerations-impl.cpp
    ${toolkit_src_dir}/text/text-controller.cpp
    ${toolkit_src_dir}/text/text-controller-event-handler.cpp
diff --git a/dali-toolkit/internal/graphics/shaders/glyphy-common-glsl-shader.def b/dali-toolkit/internal/graphics/shaders/glyphy-common-glsl-shader.def
new file mode 100644 (file)
index 0000000..f044a16
--- /dev/null
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2012 Google, Inc. All Rights Reserved.
+ *
+ * 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.
+ *
+ * Google Author(s): Behdad Esfahbod, Maysum Panju
+ */
+
+
+#ifndef GLYPHY_INFINITY
+#define GLYPHY_INFINITY 1e9
+#endif
+#ifndef GLYPHY_EPSILON
+#define GLYPHY_EPSILON  1e-5
+#endif
+
+#ifndef GLYPHY_RGBA
+#ifdef GLYPHY_BGRA
+#define GLYPHY_RGBA(v) glyphy_bgra (v)
+#else
+#define GLYPHY_RGBA(v) glyphy_rgba (v)
+#endif
+#endif
+
+vec4 glyphy_rgba (const vec4 v)
+{
+  return v.rgba;
+}
+
+vec4 glyphy_bgra (const vec4 v)
+{
+  return v.bgra;
+}
+
+struct glyphy_arc_t
+{
+  vec2  p0;
+  vec2  p1;
+  float d;
+};
+
+struct glyphy_arc_endpoint_t
+{
+  /* Second arc endpoint */
+  vec2  p;
+  /* Infinity if this endpoint does not form an arc with the previous
+   * endpoint.  Ie. a \"move_to\".  Test with glyphy_isinf().
+   * Arc depth otherwise.  */
+  float d;
+};
+
+struct glyphy_arc_list_t
+{
+  /* Number of endpoints in the list.
+   * Will be zero if we're far away inside or outside, in which case side is set.
+   * Will be -1 if this arc-list encodes a single line, in which case line_* are set. */
+  int num_endpoints;
+
+  /* If num_endpoints is zero, this specifies whether we are inside (-1)
+   * or outside (+1).  Otherwise we're unsure (0). */
+  int side;
+  /* Offset to the arc-endpoints from the beginning of the glyph blob */
+  int offset;
+
+  /* A single line is all we care about.  It's right here. */
+  float line_angle;
+  float line_distance; /* From nominal glyph center */
+};
+
+bool glyphy_isinf (const float v)
+{
+  return abs (v) >= GLYPHY_INFINITY * .5;
+}
+
+bool glyphy_iszero (const float v)
+{
+  return abs (v) <= GLYPHY_EPSILON * 2.;
+}
+
+vec2 glyphy_ortho (const vec2 v)
+{
+  return vec2 (-v.y, v.x);
+}
+
+int glyphy_float_to_byte (const float v)
+{
+  return int (v * (256. - GLYPHY_EPSILON));
+}
+
+ivec4 glyphy_vec4_to_bytes (const vec4 v)
+{
+  return ivec4 (v * (256. - GLYPHY_EPSILON));
+}
+
+ivec2 glyphy_float_to_two_nimbles (const float v)
+{
+  int f = glyphy_float_to_byte (v);
+  return ivec2 (f / 16, int(mod (float(f), 16.)));
+}
+
+/* returns tan (2 * atan (d)) */
+float glyphy_tan2atan (const float d)
+{
+  return 2. * d / (1. - d * d);
+}
+
+glyphy_arc_endpoint_t glyphy_arc_endpoint_decode(const vec4 v, const ivec2 nominal_size)
+{
+  vec2 p = (vec2 (glyphy_float_to_two_nimbles (v.a)) + v.gb) / 16.;
+  float d = v.r;
+  if (d == 0.)
+    d = GLYPHY_INFINITY;
+  else
+#define GLYPHY_MAX_D .5
+    d = float(glyphy_float_to_byte (d) - 128) * GLYPHY_MAX_D / 127.;
+#undef GLYPHY_MAX_D
+  return glyphy_arc_endpoint_t (p * vec2(nominal_size), d);
+}
+
+vec2 glyphy_arc_center (const glyphy_arc_t a)
+{
+  return mix (a.p0, a.p1, .5) +
+        glyphy_ortho (a.p1 - a.p0) / (2. * glyphy_tan2atan (a.d));
+}
+
+bool glyphy_arc_wedge_contains (const glyphy_arc_t a, const vec2 p)
+{
+  float d2 = glyphy_tan2atan (a.d);
+  return dot (p - a.p0, (a.p1 - a.p0) * mat2(1,  d2, -d2, 1)) >= 0. &&
+        dot (p - a.p1, (a.p1 - a.p0) * mat2(1, -d2,  d2, 1)) <= 0.;
+}
+
+float glyphy_arc_wedge_signed_dist_shallow (const glyphy_arc_t a, const vec2 p)
+{
+  vec2 v = normalize (a.p1 - a.p0);
+  float line_d = dot (p - a.p0, glyphy_ortho (v));
+  if (a.d == 0.)
+    return line_d;
+
+  float d0 = dot ((p - a.p0), v);
+  if (d0 < 0.)
+    return sign (line_d) * distance (p, a.p0);
+  float d1 = dot ((a.p1 - p), v);
+  if (d1 < 0.)
+    return sign (line_d) * distance (p, a.p1);
+  float r = 2. * a.d * (d0 * d1) / (d0 + d1);
+  if (r * line_d > 0.)
+    return sign (line_d) * min (abs (line_d + r), min (distance (p, a.p0), distance (p, a.p1)));
+  return line_d + r;
+}
+
+float glyphy_arc_wedge_signed_dist (const glyphy_arc_t a, const vec2 p)
+{
+  if (abs (a.d) <= .03)
+    return glyphy_arc_wedge_signed_dist_shallow (a, p);
+  vec2 c = glyphy_arc_center (a);
+  return sign (a.d) * (distance (a.p0, c) - distance (p, c));
+}
+
+float glyphy_arc_extended_dist (const glyphy_arc_t a, const vec2 p)
+{
+  /* Note: this doesn't handle points inside the wedge. */
+  vec2 m = mix (a.p0, a.p1, .5);
+  float d2 = glyphy_tan2atan (a.d);
+  if (dot (p - m, a.p1 - m) < 0.)
+    return dot (p - a.p0, normalize ((a.p1 - a.p0) * mat2(+d2, -1, +1, +d2)));
+  else
+    return dot (p - a.p1, normalize ((a.p1 - a.p0) * mat2(-d2, -1, +1, -d2)));
+}
+
+int glyphy_arc_list_offset (const vec2 p, const ivec2 nominal_size)
+{
+  ivec2 cell = ivec2 (clamp (floor (p), vec2 (0.,0.), vec2(nominal_size - 1)));
+  return cell.y * nominal_size.x + cell.x;
+}
+
+glyphy_arc_list_t glyphy_arc_list_decode (const vec4 v, const ivec2 nominal_size)
+{
+  glyphy_arc_list_t l;
+  ivec4 iv = glyphy_vec4_to_bytes (v);
+  l.side = 0; /* unsure */
+  if (iv.r == 0)
+  { /* arc-list encoded */
+    l.offset = (iv.g * 256) + iv.b;
+    l.num_endpoints = iv.a;
+    if (l.num_endpoints == 255)
+    {
+      l.num_endpoints = 0;
+      l.side = -1;
+    }
+    else if (l.num_endpoints == 0)
+      l.side = +1;
+  }
+  else
+  { /* single line encoded */
+    l.num_endpoints = -1;
+    l.line_distance = ( float(iv.r)/32. + 0.01*float(iv.g)/82.0 - 6.) * max (float (nominal_size.x), float (nominal_size.y));
+    l.line_angle = ( -float(iv.b)/40.74 - float( iv.a )*0.0001 )-3.142;
+  }
+  return l;
+}
diff --git a/dali-toolkit/internal/graphics/shaders/glyphy-sdf-glsl-shader.def b/dali-toolkit/internal/graphics/shaders/glyphy-sdf-glsl-shader.def
new file mode 100644 (file)
index 0000000..2b5accd
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2012 Google, Inc. All Rights Reserved.
+ *
+ * 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.
+ *
+ * Google Author(s): Behdad Esfahbod, Maysum Panju
+ */
+
+#ifndef GLYPHY_TEXTURE1D_FUNC
+#define GLYPHY_TEXTURE1D_FUNC glyphy_texture1D_func
+#endif
+#ifndef GLYPHY_TEXTURE1D_EXTRA_DECLS
+#define GLYPHY_TEXTURE1D_EXTRA_DECLS
+#endif
+#ifndef GLYPHY_TEXTURE1D_EXTRA_ARGS
+#define GLYPHY_TEXTURE1D_EXTRA_ARGS
+#endif
+
+#ifndef GLYPHY_SDF_TEXTURE1D_FUNC
+#define GLYPHY_SDF_TEXTURE1D_FUNC GLYPHY_TEXTURE1D_FUNC
+#endif
+#ifndef GLYPHY_SDF_TEXTURE1D_EXTRA_DECLS
+#define GLYPHY_SDF_TEXTURE1D_EXTRA_DECLS GLYPHY_TEXTURE1D_EXTRA_DECLS
+#endif
+#ifndef GLYPHY_SDF_TEXTURE1D_EXTRA_ARGS
+#define GLYPHY_SDF_TEXTURE1D_EXTRA_ARGS GLYPHY_TEXTURE1D_EXTRA_ARGS
+#endif
+#ifndef GLYPHY_SDF_TEXTURE1D
+#define GLYPHY_SDF_TEXTURE1D(offset) GLYPHY_RGBA(GLYPHY_SDF_TEXTURE1D_FUNC (offset GLYPHY_TEXTURE1D_EXTRA_ARGS))
+#endif
+
+#ifndef GLYPHY_MAX_NUM_ENDPOINTS
+#define GLYPHY_MAX_NUM_ENDPOINTS 32
+#endif
+
+glyphy_arc_list_t glyphy_arc_list (const vec2 p, const ivec2 nominal_size GLYPHY_SDF_TEXTURE1D_EXTRA_DECLS)
+{
+  int cell_offset = glyphy_arc_list_offset (p, nominal_size);
+  vec4 arc_list_data = GLYPHY_SDF_TEXTURE1D (cell_offset);
+  return glyphy_arc_list_decode (arc_list_data, nominal_size);
+}
+
+float glyphy_sdf (const vec2 p, const ivec2 nominal_size GLYPHY_SDF_TEXTURE1D_EXTRA_DECLS)
+{
+  glyphy_arc_list_t arc_list = glyphy_arc_list (p, nominal_size  GLYPHY_SDF_TEXTURE1D_EXTRA_ARGS);
+
+  /* Short-circuits */
+  if (arc_list.num_endpoints == 0)
+  {
+    /* far-away cell */
+    return GLYPHY_INFINITY * float(arc_list.side);
+  }
+  if (arc_list.num_endpoints == -1)
+  {
+    /* single-line */
+    float angle = arc_list.line_angle;
+    vec2 n = vec2 (cos (angle), sin (angle));
+    return dot (p - (vec2(nominal_size) * .5), n) - arc_list.line_distance;
+  }
+
+  float side = float(arc_list.side);
+  float min_dist = GLYPHY_INFINITY;
+  glyphy_arc_t closest_arc;
+
+  glyphy_arc_endpoint_t endpoint_prev, endpoint;
+  endpoint_prev = glyphy_arc_endpoint_decode (GLYPHY_SDF_TEXTURE1D (arc_list.offset), nominal_size);
+  for (int i = 1; i < GLYPHY_MAX_NUM_ENDPOINTS; i++)
+  {
+    if (i >= arc_list.num_endpoints)
+    {
+      break;
+    }
+    endpoint = glyphy_arc_endpoint_decode (GLYPHY_SDF_TEXTURE1D (arc_list.offset + i), nominal_size);
+    glyphy_arc_t a = glyphy_arc_t (endpoint_prev.p, endpoint.p, endpoint.d);
+    endpoint_prev = endpoint;
+    if (glyphy_isinf (a.d)) continue;
+
+    if (glyphy_arc_wedge_contains (a, p))
+    {
+      float sdist = glyphy_arc_wedge_signed_dist (a, p);
+      float udist = abs (sdist) * (1. - GLYPHY_EPSILON);
+      if (udist <= min_dist)
+      {
+        min_dist = udist;
+        side = sign (sdist);
+      }
+    }
+    else
+    {
+      float udist = min (distance (p, a.p0), distance (p, a.p1));
+      if (udist < min_dist)
+      {
+        min_dist = udist;
+        side = 0.; /* unsure */
+        closest_arc = a;
+      }
+      else if (side == 0. && udist == min_dist)
+      {
+        /* If this new distance is the same as the current minimum,
+         * compare extended distances.  Take the sign from the arc
+         * with larger extended distance. */
+        float old_ext_dist = glyphy_arc_extended_dist (closest_arc, p);
+        float new_ext_dist = glyphy_arc_extended_dist (a, p);
+
+        float ext_dist = abs (new_ext_dist) <= abs (old_ext_dist) ?
+                         old_ext_dist : new_ext_dist;
+
+#ifdef GLYPHY_SDF_PSEUDO_DISTANCE
+        /* For emboldening and stuff: */
+        min_dist = abs (ext_dist);
+#endif
+        side = sign (ext_dist);
+      }
+    }
+  }
+
+  if (side == 0.)
+  {
+    // Technically speaking this should not happen, but it does.  So try to fix it.
+    float ext_dist = glyphy_arc_extended_dist (closest_arc, p);
+    side = sign (ext_dist);
+  }
+
+  return min_dist * side;
+}
+
+float glyphy_point_dist (const vec2 p, const ivec2 nominal_size GLYPHY_SDF_TEXTURE1D_EXTRA_DECLS)
+{
+  glyphy_arc_list_t arc_list = glyphy_arc_list (p, nominal_size  GLYPHY_SDF_TEXTURE1D_EXTRA_ARGS);
+
+  float side = float(arc_list.side);
+  float min_dist = GLYPHY_INFINITY;
+
+  if (arc_list.num_endpoints == 0)
+    return min_dist;
+
+  glyphy_arc_endpoint_t endpoint;
+  for (int i = 0; i < GLYPHY_MAX_NUM_ENDPOINTS; i++)
+  {
+    if (i >= arc_list.num_endpoints)
+    {
+      break;
+    }
+    endpoint = glyphy_arc_endpoint_decode (GLYPHY_SDF_TEXTURE1D (arc_list.offset + i), nominal_size);
+    if (glyphy_isinf (endpoint.d)) continue;
+    min_dist = min (min_dist, distance (p, endpoint.p));
+  }
+
+  return min_dist;
+}
diff --git a/dali-toolkit/internal/graphics/shaders/glyphy-shader-extention-prefix.def b/dali-toolkit/internal/graphics/shaders/glyphy-shader-extention-prefix.def
new file mode 100644 (file)
index 0000000..3f7237d
--- /dev/null
@@ -0,0 +1,3 @@
+#extension GL_OES_standard_derivatives : enable
+precision highp float;
+precision highp int;
diff --git a/dali-toolkit/internal/graphics/shaders/glyphy-shader-fragment-prefix.frag b/dali-toolkit/internal/graphics/shaders/glyphy-shader-fragment-prefix.frag
new file mode 100644 (file)
index 0000000..4cb1423
--- /dev/null
@@ -0,0 +1,34 @@
+struct Material
+{
+  mediump float mOpacity;
+  mediump float mShininess;
+  lowp    vec4  mAmbient;
+  lowp    vec4  mDiffuse;
+  lowp    vec4  mSpecular;
+  lowp    vec4  mEmissive;
+};
+
+uniform sampler2D     sTexture;
+uniform sampler2D     sOpacityTexture;
+uniform sampler2D     sNormalMapTexture;
+uniform sampler2D     sEffect;
+varying mediump vec2 vTexCoord;
+uniform Material      uMaterial;
+uniform lowp  vec4    uColor;
+varying highp vec4    vVertex;
+varying highp vec3    vNormal;
+varying mediump vec4  vColor;
+uniform vec4 u_atlas_info;
+
+#define GLYPHY_TEXTURE1D_EXTRA_DECLS , sampler2D _tex, ivec4 _atlas_info, ivec2 _atlas_pos
+#define GLYPHY_TEXTURE1D_EXTRA_ARGS , _tex, _atlas_info, _atlas_pos
+#define GLYPHY_DEMO_EXTRA_ARGS , sTexture, uu_atlas_info, gi.atlas_pos
+
+vec4 glyphy_texture1D_func (int offset GLYPHY_TEXTURE1D_EXTRA_DECLS)
+{
+  ivec2 item_geom = _atlas_info.zw;
+  vec2 pos = (vec2 (_atlas_pos.xy * item_geom +
+                    ivec2 (mod (float (offset), float (item_geom.x)), offset / item_geom.x)) +
+             + vec2 (.5, .5)) / vec2(_atlas_info.xy);
+  return texture2D (_tex, pos);
+}
diff --git a/dali-toolkit/internal/graphics/shaders/glyphy-shader-main.frag b/dali-toolkit/internal/graphics/shaders/glyphy-shader-main.frag
new file mode 100644 (file)
index 0000000..4fc43da
--- /dev/null
@@ -0,0 +1,66 @@
+uniform float u_contrast;
+uniform float u_gamma_adjust;
+uniform float u_outline_thickness;
+uniform float u_outline;
+uniform float u_boldness;
+
+varying vec4 v_glyph;
+
+#define SQRT2_2 0.70711 /* 1 / sqrt(2.) */
+#define SQRT2   1.41421
+
+struct glyph_info_t
+{
+  ivec2 nominal_size;
+  ivec2 atlas_pos;
+};
+
+glyph_info_t glyph_info_decode (vec4 v)
+{
+  glyph_info_t gi;
+  gi.nominal_size = (ivec2 (mod (v.zw, 256.)) + 2) / 4;
+  gi.atlas_pos = ivec2 (v_glyph.zw) / 256;
+  return gi;
+}
+
+
+float antialias (float d)
+{
+  return smoothstep (-.75, +.75, d);
+}
+
+vec4 source_over (const vec4 src, const vec4 dst)
+{
+  // http://dev.w3.org/fxtf/compositing-1/#porterduffcompositingoperators_srcover
+  float alpha = src.a + (dst.a * (1. - src.a));
+  return vec4 (((src.rgb * src.a) + (dst.rgb * dst.a * (1. - src.a))) / alpha, alpha);
+}
+
+void main()
+{
+  vec2 p = v_glyph.xy;
+  glyph_info_t gi = glyph_info_decode (v_glyph);
+
+  /* isotropic antialiasing */
+  vec2 dpdx = dFdx (p);
+  vec2 dpdy = dFdy (p);
+  float m = length (vec2 (length (dpdx), length (dpdy))) * SQRT2_2;
+
+  vec4 color = vec4( vColor.rgb * uColor.rgb, vColor.a * uColor.a );
+
+  ivec4 uu_atlas_info = ivec4( u_atlas_info );
+  float gsdist = glyphy_sdf (p, gi.nominal_size GLYPHY_DEMO_EXTRA_ARGS);
+  float sdist = gsdist / m * u_contrast;
+
+  sdist -= u_boldness * 10.;
+  if ( glyphy_iszero( u_outline ) )
+    sdist = abs (sdist) - u_outline_thickness * .5;
+  if (sdist > 1.)
+    discard;
+  float alpha = antialias (-sdist);
+  if (u_gamma_adjust != 1.)
+    alpha = pow (alpha, 1./u_gamma_adjust);
+  color = vec4 (color.rgb,color.a * alpha);
+
+  gl_FragColor = color;
+}
diff --git a/dali-toolkit/internal/graphics/shaders/glyphy-shader-main.vert b/dali-toolkit/internal/graphics/shaders/glyphy-shader-main.vert
new file mode 100644 (file)
index 0000000..9b0f342
--- /dev/null
@@ -0,0 +1,31 @@
+uniform   mediump mat4    uProjection;
+uniform   mediump mat4    uModelView;
+uniform   mediump mat4    uMvpMatrix;
+uniform           bool    uTextureMapped;
+uniform   mediump vec4    uCustomTextureCoords;
+attribute highp   vec2    aTexCoord;
+varying   mediump vec2    vTexCoord;
+uniform   mat3            uModelViewIT;
+attribute mediump vec3    aNormal;
+varying   mediump vec3    vNormal;
+attribute mediump vec2    aPosition;
+varying   mediump vec4    vVertex;
+attribute mediump vec4    aColor;
+varying   mediump vec4    vColor;
+varying vec4 v_glyph;
+
+vec4 glyph_vertex_transcode (vec2 v)
+{
+  ivec2 g = ivec2 (v);
+  ivec2 corner = ivec2 (mod (v, 2.));
+  g /= 2;
+  ivec2 nominal_size = ivec2 (mod (vec2(g), 64.));
+  return vec4 (corner * nominal_size, g * 4);
+}
+
+void main()
+{
+  gl_Position = uMvpMatrix * vec4 (aPosition, 0.0, 1.0);
+  v_glyph = glyph_vertex_transcode (aTexCoord);
+  vColor = aColor;
+}
\ No newline at end of file
diff --git a/dali-toolkit/internal/text/hyphenator.cpp b/dali-toolkit/internal/text/hyphenator.cpp
new file mode 100644 (file)
index 0000000..66f99a3
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2021 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/text/hyphenator.h>
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/text-abstraction/hyphenation.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/character-set-conversion.h>
+
+#include <cstring> // for strcmp
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+const char* UTF8 = "UTF-8";
+
+Vector<bool> GetWordHyphens(const Character* word,
+                            Length           wordSize,
+                            const char*      lang)
+{
+  Vector<bool> hyphens;
+
+  if(0u == wordSize || word == nullptr)
+  {
+    // Nothing to do if there are no characters.
+    return hyphens;
+  }
+
+  TextAbstraction::Hyphenation hyphenation = TextAbstraction::Hyphenation::Get();
+
+  // first get the needed encoding
+  std::string text;
+  if(strcmp(hyphenation.GetDictionaryEncoding(lang), UTF8) == 0)
+  {
+    Utf32ToUtf8(word, wordSize, text);
+  }
+  else
+  {
+    text = std::string((char*)word, (size_t)(wordSize * sizeof(Character)));
+  }
+
+  return hyphenation.GetWordHyphens(text.c_str(), (int)text.length(), lang);
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/text/hyphenator.h b/dali-toolkit/internal/text/hyphenator.h
new file mode 100644 (file)
index 0000000..eef2246
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef DALI_TOOLKIT_TEXT_HYPHENATOR_H
+#define DALI_TOOLKIT_TEXT_HYPHENATOR_H
+
+/*
+ * Copyright (c) 2021 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/dali-vector.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/font-run.h>
+#include <dali-toolkit/internal/text/script-run.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Text
+{
+/**
+ * Gets a vector booleans that indicates possible hyphen locations.
+ *
+ * @param[in] word the word to get possible hyphens for.
+ * @param[in] wordSize the word size in bytes.
+ * @param[in] lang the language for the word
+ *
+ * @return vector of boolean, true if possible to hyphenate at this character position.
+ */
+Vector<bool> GetWordHyphens(const Character* word,
+                            Length           wordSize,
+                            const char*      lang);
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_HYPHENATOR_H
index fcf5f5e..25f83d1 100644 (file)
@@ -44,11 +44,12 @@ namespace
 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_LAYOUT");
 #endif
 
-const float              MAX_FLOAT     = std::numeric_limits<float>::max();
-const CharacterDirection LTR           = false;
-const CharacterDirection RTL           = !LTR;
-const float              LINE_SPACING  = 0.f;
-const float              MIN_LINE_SIZE = 0.f;
+const float              MAX_FLOAT      = std::numeric_limits<float>::max();
+const CharacterDirection LTR            = false;
+const CharacterDirection RTL            = !LTR;
+const float              LINE_SPACING   = 0.f;
+const float              MIN_LINE_SIZE  = 0.f;
+const Character          HYPHEN_UNICODE = 0x002D;
 
 inline bool isEmptyLineAtLast(const Vector<LineRun>& lines, const Vector<LineRun>::Iterator& line)
 {
@@ -448,7 +449,11 @@ struct Engine::Impl
     const Length totalNumberOfGlyphs = parameters.textModel->mVisualModel->mGlyphs.Count();
 
     const bool isMultiline   = mLayout == MULTI_LINE_BOX;
-    const bool isWordLaidOut = parameters.textModel->mLineWrapMode == Text::LineWrap::WORD;
+    const bool isWordLaidOut = parameters.textModel->mLineWrapMode == Text::LineWrap::WORD ||
+                               (parameters.textModel->mLineWrapMode == (Text::LineWrap::Mode)DevelText::LineWrap::HYPHENATION) ||
+                               (parameters.textModel->mLineWrapMode == (Text::LineWrap::Mode)DevelText::LineWrap::MIXED);
+    const bool isHyphenMode = parameters.textModel->mLineWrapMode == (Text::LineWrap::Mode)DevelText::LineWrap::HYPHENATION;
+    const bool isMixedMode  = parameters.textModel->mLineWrapMode == (Text::LineWrap::Mode)DevelText::LineWrap::MIXED;
 
     // The last glyph to be laid-out.
     const GlyphIndex lastGlyphOfParagraphPlusOne = parameters.startGlyphIndex + parameters.numberOfGlyphs;
@@ -486,7 +491,10 @@ struct Engine::Impl
     FontId lastFontId = glyphMetrics.fontId;
     UpdateLineHeight(glyphMetrics, tmpLineLayout);
 
-    bool oneWordLaidOut = false;
+    bool       oneWordLaidOut   = false;
+    bool       oneHyphenLaidOut = false;
+    GlyphIndex hyphenIndex      = 0;
+    GlyphInfo  hyphenGlyph;
 
     for(GlyphIndex glyphIndex = lineLayout.glyphIndex;
         glyphIndex < lastGlyphOfParagraphPlusOne;)
@@ -565,7 +573,15 @@ struct Engine::Impl
          (tmpLineLayout.length > parameters.boundingBox.width))
       {
         // Current word does not fit in the box's width.
-        if(!oneWordLaidOut || completelyFill)
+        if(((oneHyphenLaidOut && isHyphenMode) ||
+            (!oneWordLaidOut && isMixedMode && oneHyphenLaidOut)) &&
+           !completelyFill)
+        {
+          parameters.textModel->mVisualModel->mHyphen.glyph.PushBack(hyphenGlyph);
+          parameters.textModel->mVisualModel->mHyphen.index.PushBack(hyphenIndex + 1);
+        }
+
+        if((!oneWordLaidOut && !oneHyphenLaidOut) || completelyFill)
         {
           DALI_LOG_INFO(gLogFilter, Debug::Verbose, "  Break the word by character\n");
 
@@ -608,7 +624,7 @@ struct Engine::Impl
          (TextAbstraction::LINE_MUST_BREAK == lineBreakInfo))
       {
         LineLayout currentLineLayout = lineLayout;
-
+        oneHyphenLaidOut             = false;
         // Must break the line. Update the line layout and return.
         MergeLineLayout(lineLayout, tmpLineLayout);
 
@@ -631,7 +647,8 @@ struct Engine::Impl
       if(isMultiline &&
          (TextAbstraction::LINE_ALLOW_BREAK == lineBreakInfo))
       {
-        oneWordLaidOut = isWordLaidOut;
+        oneHyphenLaidOut = false;
+        oneWordLaidOut   = isWordLaidOut;
         DALI_LOG_INFO(gLogFilter, Debug::Verbose, "  One word laid-out\n");
 
         // Current glyph is the last one of the current word.
@@ -641,6 +658,33 @@ struct Engine::Impl
         tmpLineLayout.Clear();
       }
 
+      if(isMultiline &&
+         ((isHyphenMode || (!oneWordLaidOut && isMixedMode))) &&
+         (TextAbstraction::LINE_HYPHENATION_BREAK == lineBreakInfo))
+      {
+        hyphenGlyph        = GlyphInfo();
+        hyphenGlyph.fontId = glyphsBuffer[glyphIndex].fontId;
+
+        TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
+        hyphenGlyph.index                      = fontClient.GetGlyphIndex(hyphenGlyph.fontId, HYPHEN_UNICODE);
+
+        mMetrics->GetGlyphMetrics(&hyphenGlyph, 1);
+
+        if((tmpLineLayout.length + hyphenGlyph.width) <= parameters.boundingBox.width)
+        {
+          hyphenIndex      = glyphIndex;
+          oneHyphenLaidOut = true;
+
+          DALI_LOG_INFO(gLogFilter, Debug::Verbose, "  One hyphen laid-out\n");
+
+          // Current glyph is the last one of the current word hyphen.
+          // Add the temporal layout to the current one.
+          MergeLineLayout(lineLayout, tmpLineLayout);
+
+          tmpLineLayout.Clear();
+        }
+      }
+
       glyphIndex += numberOfGLyphsInGroup;
     }
 
@@ -1059,6 +1103,9 @@ struct Engine::Impl
     DALI_LOG_INFO(gLogFilter, Debug::Verbose, "-->LayoutText\n");
     DALI_LOG_INFO(gLogFilter, Debug::Verbose, "  box size %f, %f\n", layoutParameters.boundingBox.width, layoutParameters.boundingBox.height);
 
+    layoutParameters.textModel->mVisualModel->mHyphen.glyph.Clear();
+    layoutParameters.textModel->mVisualModel->mHyphen.index.Clear();
+
     Vector<LineRun>& lines = layoutParameters.textModel->mVisualModel->mLines;
 
     if(0u == layoutParameters.numberOfGlyphs)
@@ -1271,6 +1318,17 @@ struct Engine::Impl
 
       if(ellipsis)
       {
+        //clear hyphen from ellipsis line
+        const Length* hyphenIndices = layoutParameters.textModel->mVisualModel->mHyphen.index.Begin();
+        Length        hyphensCount  = layoutParameters.textModel->mVisualModel->mHyphen.glyph.Size();
+
+        while(hyphenIndices && hyphensCount > 0 && hyphenIndices[hyphensCount - 1] >= layout.glyphIndex)
+        {
+          layoutParameters.textModel->mVisualModel->mHyphen.index.Remove(layoutParameters.textModel->mVisualModel->mHyphen.index.Begin() + hyphensCount - 1);
+          layoutParameters.textModel->mVisualModel->mHyphen.glyph.Remove(layoutParameters.textModel->mVisualModel->mHyphen.glyph.Begin() + hyphensCount - 1);
+          hyphensCount--;
+        }
+
         // No more lines to layout.
         break;
       }
index 1b1fc35..1023dc4 100644 (file)
@@ -419,16 +419,19 @@ struct AtlasRenderer::Impl
     Vector<Extent>          extents;
     mDepth = depth;
 
-    const Vector2& textSize(view.GetLayoutSize());
-    const Vector2  halfTextSize(textSize * 0.5f);
-    const Vector2& shadowOffset(view.GetShadowOffset());
-    const Vector4& shadowColor(view.GetShadowColor());
-    const bool     underlineEnabled = view.IsUnderlineEnabled();
-    const Vector4& underlineColor(view.GetUnderlineColor());
-    const float    underlineHeight = view.GetUnderlineHeight();
-    const uint16_t outlineWidth    = view.GetOutlineWidth();
-    const Vector4& outlineColor(view.GetOutlineColor());
-    const bool     isOutline = 0u != outlineWidth;
+    const Vector2&   textSize(view.GetLayoutSize());
+    const Vector2    halfTextSize(textSize * 0.5f);
+    const Vector2&   shadowOffset(view.GetShadowOffset());
+    const Vector4&   shadowColor(view.GetShadowColor());
+    const bool       underlineEnabled = view.IsUnderlineEnabled();
+    const Vector4&   underlineColor(view.GetUnderlineColor());
+    const float      underlineHeight = view.GetUnderlineHeight();
+    const uint16_t   outlineWidth    = view.GetOutlineWidth();
+    const Vector4&   outlineColor(view.GetOutlineColor());
+    const bool       isOutline     = 0u != outlineWidth;
+    const GlyphInfo* hyphens       = view.GetHyphens();
+    const Length*    hyphenIndices = view.GetHyphenIndices();
+    const Length     hyphensCount  = view.GetHyphensCount();
 
     const bool useDefaultColor = (NULL == colorsBuffer);
 
@@ -460,6 +463,7 @@ struct AtlasRenderer::Impl
     const GlyphInfo* const glyphsBuffer    = glyphs.Begin();
     const Vector2* const   positionsBuffer = positions.Begin();
     const Vector2          lineOffsetPosition(minLineOffset, 0.f);
+    uint32_t               hyphenIndex = 0;
 
     //For septated underlined chunks. (this is for Markup case)
     uint32_t underlineChunkId = 0u; // give id for each chunk.
@@ -467,9 +471,20 @@ struct AtlasRenderer::Impl
 
     for(uint32_t i = 0, glyphSize = glyphs.Size(); i < glyphSize; ++i)
     {
-      const GlyphInfo& glyph             = *(glyphsBuffer + i);
-      const bool       isGlyphUnderlined = underlineEnabled || IsGlyphUnderlined(i, underlineRuns);
-      thereAreUnderlinedGlyphs           = thereAreUnderlinedGlyphs || isGlyphUnderlined;
+      GlyphInfo glyph;
+      bool      addHyphen = ((hyphenIndex < hyphensCount) && hyphenIndices && (i == hyphenIndices[hyphenIndex]));
+      if(addHyphen && hyphens)
+      {
+        glyph = hyphens[hyphenIndex];
+        i--;
+      }
+      else
+      {
+        glyph = *(glyphsBuffer + i);
+      }
+
+      const bool isGlyphUnderlined = underlineEnabled || IsGlyphUnderlined(i, underlineRuns);
+      thereAreUnderlinedGlyphs     = thereAreUnderlinedGlyphs || isGlyphUnderlined;
 
       // No operation for white space
       if(glyph.width && glyph.height)
@@ -529,8 +544,16 @@ struct AtlasRenderer::Impl
         }
 
         // Move the origin (0,0) of the mesh to the center of the actor
-        const Vector2& temp     = *(positionsBuffer + i);
-        const Vector2  position = Vector2(roundf(temp.x), temp.y) - halfTextSize - lineOffsetPosition; // roundf() avoids pixel alignment issues.
+        Vector2 position = *(positionsBuffer + i);
+
+        if(addHyphen)
+        {
+          GlyphInfo tempInfo = *(glyphsBuffer + i);
+          position.x         = position.x + tempInfo.advance - tempInfo.xBearing + glyph.xBearing;
+          position.y += tempInfo.yBearing - glyph.yBearing;
+        }
+
+        position = Vector2(roundf(position.x), position.y) - halfTextSize - lineOffsetPosition; // roundf() avoids pixel alignment issues.
 
         if(0u != slot.mImageId) // invalid slot id, glyph has failed to be added to atlas
         {
@@ -588,6 +611,11 @@ struct AtlasRenderer::Impl
         //Keep status of underlined for previous glyph to check consecutive indices
         isPreUnderlined = isGlyphUnderlined;
       }
+
+      if(addHyphen)
+      {
+        hyphenIndex++;
+      }
     } // glyphs
 
     // Now remove references for the old text
index 60888db..40d96b8 100644 (file)
@@ -618,6 +618,9 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const unsigned int bufferWidth,
   const Vector2* const    positionBuffer     = mModel->GetLayout();
   const Vector4* const    colorsBuffer       = mModel->GetColors();
   const ColorIndex* const colorIndexBuffer   = mModel->GetColorIndices();
+  const GlyphInfo*        hyphens            = mModel->GetHyphens();
+  const Length*           hyphenIndices      = mModel->GetHyphenIndices();
+  const Length            hyphensCount       = mModel->GetHyphensCount();
 
   // Whether to use the default color.
   const bool     useDefaultColor = (NULL == colorsBuffer);
@@ -643,7 +646,8 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const unsigned int bufferWidth,
   }
 
   // Get a handle of the font client. Used to retrieve the bitmaps of the glyphs.
-  TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
+  TextAbstraction::FontClient fontClient  = TextAbstraction::FontClient::Get();
+  Length                      hyphenIndex = 0;
 
   // Traverses the lines of the text.
   for(LineIndex lineIndex = 0u; lineIndex < modelNumberOfLines; ++lineIndex)
@@ -708,6 +712,7 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const unsigned int bufferWidth,
     float lineExtentLeft  = bufferWidth;
     float lineExtentRight = 0.0f;
     float baseline        = 0.0f;
+    bool  addHyphen       = false;
 
     // Traverses the glyphs of the line.
     const GlyphIndex endGlyphIndex = std::min(numberOfGlyphs, line.glyphRun.glyphIndex + line.glyphRun.numberOfGlyphs);
@@ -720,7 +725,17 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const unsigned int bufferWidth,
       }
 
       // Retrieve the glyph's info.
-      const GlyphInfo* const glyphInfo = glyphsBuffer + glyphIndex;
+      const GlyphInfo* glyphInfo;
+
+      if(addHyphen && hyphens)
+      {
+        glyphInfo = hyphens + hyphenIndex;
+        hyphenIndex++;
+      }
+      else
+      {
+        glyphInfo = glyphsBuffer + glyphIndex;
+      }
 
       if((glyphInfo->width < Math::MACHINE_EPSILON_1000) ||
          (glyphInfo->height < Math::MACHINE_EPSILON_1000))
@@ -740,21 +755,29 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const unsigned int bufferWidth,
       } // underline
 
       // Retrieves the glyph's position.
-      const Vector2* const position = positionBuffer + glyphIndex;
-      if(baseline < position->y + glyphInfo->yBearing)
+      Vector2 position = *(positionBuffer + glyphIndex);
+
+      if(addHyphen)
+      {
+        GlyphInfo tempInfo = *(glyphsBuffer + glyphIndex);
+        position.x         = position.x + tempInfo.advance - tempInfo.xBearing + glyphInfo->xBearing;
+        position.y         = -glyphInfo->yBearing;
+      }
+
+      if(baseline < position.y + glyphInfo->yBearing)
       {
-        baseline = position->y + glyphInfo->yBearing;
+        baseline = position.y + glyphInfo->yBearing;
       }
 
       // Calculate the positions of leftmost and rightmost glyphs in the current line
-      if(position->x < lineExtentLeft)
+      if(position.x < lineExtentLeft)
       {
-        lineExtentLeft = position->x;
+        lineExtentLeft = position.x;
       }
 
-      if(position->x + glyphInfo->width > lineExtentRight)
+      if(position.x + glyphInfo->width > lineExtentRight)
       {
-        lineExtentRight = position->x + glyphInfo->width;
+        lineExtentRight = position.x + glyphInfo->width;
       }
 
       // Retrieves the glyph's color.
@@ -812,7 +835,7 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const unsigned int bufferWidth,
 
         // Set the buffer of the glyph's bitmap into the final bitmap's buffer
         TypesetGlyph(glyphData,
-                     position,
+                     &position,
                      &color,
                      style,
                      pixelFormat);
@@ -828,6 +851,17 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const unsigned int bufferWidth,
         delete[] glyphData.glyphBitmap.buffer;
         glyphData.glyphBitmap.buffer = NULL;
       }
+
+      while((hyphenIndex < hyphensCount) && (glyphIndex > hyphenIndices[hyphenIndex]))
+      {
+        hyphenIndex++;
+      }
+
+      addHyphen = ((hyphenIndex < hyphensCount) && hyphenIndices && ((glyphIndex + 1) == hyphenIndices[hyphenIndex]));
+      if(addHyphen)
+      {
+        glyphIndex--;
+      }
     }
 
     // Draw the underline from the leftmost glyph to the rightmost glyph
diff --git a/dali-toolkit/internal/text/rendering/vector-based/glyphy-shader/glyphy-common-glsl.h b/dali-toolkit/internal/text/rendering/vector-based/glyphy-shader/glyphy-common-glsl.h
deleted file mode 100644 (file)
index 48a8335..0000000
+++ /dev/null
@@ -1,229 +0,0 @@
-static const char* glyphy_common_glsl =
-  "/*\n"
-  " * Copyright 2012 Google, Inc. All Rights Reserved.\n"
-  " *\n"
-  " * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
-  " * you may not use this file except in compliance with the License.\n"
-  " * You may obtain a copy of the License at\n"
-  " *\n"
-  " *     http://www.apache.org/licenses/LICENSE-2.0\n"
-  " *\n"
-  " * Unless required by applicable law or agreed to in writing, software\n"
-  " * distributed under the License is distributed on an \"AS IS\" BASIS,\n"
-  " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
-  " * See the License for the specific language governing permissions and\n"
-  " * limitations under the License.\n"
-  " *\n"
-  " * Google Author(s): Behdad Esfahbod, Maysum Panju\n"
-  " */\n"
-  "\n"
-  "\n"
-  "#ifndef GLYPHY_INFINITY\n"
-  "#  define GLYPHY_INFINITY 1e9\n"
-  "#endif\n"
-  "#ifndef GLYPHY_EPSILON\n"
-  "#  define GLYPHY_EPSILON  1e-5\n"
-  "#endif\n"
-  "\n"
-  "#ifndef GLYPHY_RGBA\n"
-  "#  ifdef GLYPHY_BGRA\n"
-  "#    define GLYPHY_RGBA(v) glyphy_bgra (v)\n"
-  "#  else\n"
-  "#    define GLYPHY_RGBA(v) glyphy_rgba (v)\n"
-  "#  endif\n"
-  "#endif\n"
-  "\n"
-  "vec4\n"
-  "glyphy_rgba (const vec4 v)\n"
-  "{\n"
-  "  return v.rgba;\n"
-  "}\n"
-  "\n"
-  "vec4\n"
-  "glyphy_bgra (const vec4 v)\n"
-  "{\n"
-  "  return v.bgra;\n"
-  "}\n"
-  "\n"
-  "\n"
-  "struct glyphy_arc_t {\n"
-  "  vec2  p0;\n"
-  "  vec2  p1;\n"
-  "  float d;\n"
-  "};\n"
-  "\n"
-  "struct glyphy_arc_endpoint_t {\n"
-  "  /* Second arc endpoint */\n"
-  "  vec2  p;\n"
-  "  /* Infinity if this endpoint does not form an arc with the previous\n"
-  "   * endpoint.  Ie. a \"move_to\".  Test with glyphy_isinf().\n"
-  "   * Arc depth otherwise.  */\n"
-  "  float d;\n"
-  "};\n"
-  "\n"
-  "struct glyphy_arc_list_t {\n"
-  "  /* Number of endpoints in the list.\n"
-  "   * Will be zero if we're far away inside or outside, in which case side is set.\n"
-  "   * Will be -1 if this arc-list encodes a single line, in which case line_* are set. */\n"
-  "  int num_endpoints;\n"
-  "\n"
-  "  /* If num_endpoints is zero, this specifies whether we are inside (-1)\n"
-  "   * or outside (+1).  Otherwise we're unsure (0). */\n"
-  "  int side;\n"
-  "  /* Offset to the arc-endpoints from the beginning of the glyph blob */\n"
-  "  int offset;\n"
-  "\n"
-  "  /* A single line is all we care about.  It's right here. */\n"
-  "  float line_angle;\n"
-  "  float line_distance; /* From nominal glyph center */\n"
-  "};\n"
-  "\n"
-  "bool\n"
-  "glyphy_isinf (const float v)\n"
-  "{\n"
-  "  return abs (v) >= GLYPHY_INFINITY * .5;\n"
-  "}\n"
-  "\n"
-  "bool\n"
-  "glyphy_iszero (const float v)\n"
-  "{\n"
-  "  return abs (v) <= GLYPHY_EPSILON * 2.;\n"
-  "}\n"
-  "\n"
-  "vec2\n"
-  "glyphy_ortho (const vec2 v)\n"
-  "{\n"
-  "  return vec2 (-v.y, v.x);\n"
-  "}\n"
-  "\n"
-  "int\n"
-  "glyphy_float_to_byte (const float v)\n"
-  "{\n"
-  "  return int (v * (256. - GLYPHY_EPSILON));\n"
-  "}\n"
-  "\n"
-  "ivec4\n"
-  "glyphy_vec4_to_bytes (const vec4 v)\n"
-  "{\n"
-  "  return ivec4 (v * (256. - GLYPHY_EPSILON));\n"
-  "}\n"
-  "\n"
-  "ivec2\n"
-  "glyphy_float_to_two_nimbles (const float v)\n"
-  "{\n"
-  "  int f = glyphy_float_to_byte (v);\n"
-  "  return ivec2 (f / 16, int(mod (float(f), 16.)));\n"
-  "}\n"
-  "\n"
-  "/* returns tan (2 * atan (d)) */\n"
-  "float\n"
-  "glyphy_tan2atan (const float d)\n"
-  "{\n"
-  "  return 2. * d / (1. - d * d);\n"
-  "}\n"
-  "\n"
-  "glyphy_arc_endpoint_t\n"
-  "glyphy_arc_endpoint_decode (const vec4 v, const ivec2 nominal_size)\n"
-  "{\n"
-  "  vec2 p = (vec2 (glyphy_float_to_two_nimbles (v.a)) + v.gb) / 16.;\n"
-  "  float d = v.r;\n"
-  "  if (d == 0.)\n"
-  "    d = GLYPHY_INFINITY;\n"
-  "  else\n"
-  "#define GLYPHY_MAX_D .5\n"
-  "    d = float(glyphy_float_to_byte (d) - 128) * GLYPHY_MAX_D / 127.;\n"
-  "#undef GLYPHY_MAX_D\n"
-  "  return glyphy_arc_endpoint_t (p * vec2(nominal_size), d);\n"
-  "}\n"
-  "\n"
-  "vec2\n"
-  "glyphy_arc_center (const glyphy_arc_t a)\n"
-  "{\n"
-  "  return mix (a.p0, a.p1, .5) +\n"
-  "     glyphy_ortho (a.p1 - a.p0) / (2. * glyphy_tan2atan (a.d));\n"
-  "}\n"
-  "\n"
-  "bool\n"
-  "glyphy_arc_wedge_contains (const glyphy_arc_t a, const vec2 p)\n"
-  "{\n"
-  "  float d2 = glyphy_tan2atan (a.d);\n"
-  "  return dot (p - a.p0, (a.p1 - a.p0) * mat2(1,  d2, -d2, 1)) >= 0. &&\n"
-  "     dot (p - a.p1, (a.p1 - a.p0) * mat2(1, -d2,  d2, 1)) <= 0.;\n"
-  "}\n"
-  "\n"
-  "float\n"
-  "glyphy_arc_wedge_signed_dist_shallow (const glyphy_arc_t a, const vec2 p)\n"
-  "{\n"
-  "  vec2 v = normalize (a.p1 - a.p0);\n"
-  "  float line_d = dot (p - a.p0, glyphy_ortho (v));\n"
-  "  if (a.d == 0.)\n"
-  "    return line_d;\n"
-  "\n"
-  "  float d0 = dot ((p - a.p0), v);\n"
-  "  if (d0 < 0.)\n"
-  "    return sign (line_d) * distance (p, a.p0);\n"
-  "  float d1 = dot ((a.p1 - p), v);\n"
-  "  if (d1 < 0.)\n"
-  "    return sign (line_d) * distance (p, a.p1);\n"
-  "  float r = 2. * a.d * (d0 * d1) / (d0 + d1);\n"
-  "  if (r * line_d > 0.)\n"
-  "    return sign (line_d) * min (abs (line_d + r), min (distance (p, a.p0), distance (p, a.p1)));\n"
-  "  return line_d + r;\n"
-  "}\n"
-  "\n"
-  "float\n"
-  "glyphy_arc_wedge_signed_dist (const glyphy_arc_t a, const vec2 p)\n"
-  "{\n"
-  "  if (abs (a.d) <= .03)\n"
-  "    return glyphy_arc_wedge_signed_dist_shallow (a, p);\n"
-  "  vec2 c = glyphy_arc_center (a);\n"
-  "  return sign (a.d) * (distance (a.p0, c) - distance (p, c));\n"
-  "}\n"
-  "\n"
-  "float\n"
-  "glyphy_arc_extended_dist (const glyphy_arc_t a, const vec2 p)\n"
-  "{\n"
-  "  /* Note: this doesn't handle points inside the wedge. */\n"
-  "  vec2 m = mix (a.p0, a.p1, .5);\n"
-  "  float d2 = glyphy_tan2atan (a.d);\n"
-  "  if (dot (p - m, a.p1 - m) < 0.)\n"
-  "    return dot (p - a.p0, normalize ((a.p1 - a.p0) * mat2(+d2, -1, +1, +d2)));\n"
-  "  else\n"
-  "    return dot (p - a.p1, normalize ((a.p1 - a.p0) * mat2(-d2, -1, +1, -d2)));\n"
-  "}\n"
-  "\n"
-  "int\n"
-  "glyphy_arc_list_offset (const vec2 p, const ivec2 nominal_size)\n"
-  "{\n"
-  "  ivec2 cell = ivec2 (clamp (floor (p), vec2 (0.,0.), vec2(nominal_size - 1)));\n"
-  "  return cell.y * nominal_size.x + cell.x;\n"
-  "}\n"
-  "\n"
-  "glyphy_arc_list_t\n"
-  "glyphy_arc_list_decode (const vec4 v, const ivec2 nominal_size)\n"
-  "{\n"
-  "  glyphy_arc_list_t l;\n"
-  "  ivec4 iv = glyphy_vec4_to_bytes (v);\n"
-  "  l.side = 0; /* unsure */\n"
-  "  if (iv.r == 0) { /* arc-list encoded */\n"
-  "    l.offset = (iv.g * 256) + iv.b;\n"
-  "    l.num_endpoints = iv.a;\n"
-  "    if (l.num_endpoints == 255) {\n"
-  "      l.num_endpoints = 0;\n"
-  "      l.side = -1;\n"
-  "    } else if (l.num_endpoints == 0)\n"
-  "      l.side = +1;\n"
-  "  } else { /* single line encoded */\n"
-  "    l.num_endpoints = -1;\n"
-  /*"    l.line_distance = float(((iv.r - 128) * 256 + iv.g) - 0x4000) / float (0x1FFF)\n"
-  "                    * max (float (nominal_size.x), float (nominal_size.y));\n"
-  "    l.line_angle = float(-((iv.b * 256 + iv.a) - 0x8000)) / float (0x7FFF) * 3.14159265358979;\n"*/
-  /*"    l.line_distance = float(((iv.r - 128) * 256 + iv.g) - 16384) / 8191.0 \n"
-  "                    * max (float (nominal_size.x), float (nominal_size.y));\n"
-  "    l.line_angle = float(-((iv.b * 256 + iv.a) - 32768)) / 32767. * 3.14159;\n"*/
-  "    l.line_distance = ( float(iv.r)/32. + 0.01*float(iv.g)/82.0 - 6.) \n"
-  "                    * max (float (nominal_size.x), float (nominal_size.y));\n"
-  "    l.line_angle = ( -float(iv.b)/40.74 - float( iv.a )*0.0001 )-3.142;\n"
-  "  }\n"
-  "  return l;\n"
-  "}\n";
diff --git a/dali-toolkit/internal/text/rendering/vector-based/glyphy-shader/glyphy-sdf-glsl.h b/dali-toolkit/internal/text/rendering/vector-based/glyphy-shader/glyphy-sdf-glsl.h
deleted file mode 100644 (file)
index 37b1b13..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-static const char* glyphy_sdf_glsl =
-  "/*\n"
-  " * Copyright 2012 Google, Inc. All Rights Reserved.\n"
-  " *\n"
-  " * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
-  " * you may not use this file except in compliance with the License.\n"
-  " * You may obtain a copy of the License at\n"
-  " *\n"
-  " *     http://www.apache.org/licenses/LICENSE-2.0\n"
-  " *\n"
-  " * Unless required by applicable law or agreed to in writing, software\n"
-  " * distributed under the License is distributed on an \"AS IS\" BASIS,\n"
-  " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
-  " * See the License for the specific language governing permissions and\n"
-  " * limitations under the License.\n"
-  " *\n"
-  " * Google Author(s): Behdad Esfahbod, Maysum Panju\n"
-  " */\n"
-  "\n"
-  "#ifndef GLYPHY_TEXTURE1D_FUNC\n"
-  "#define GLYPHY_TEXTURE1D_FUNC glyphy_texture1D_func\n"
-  "#endif\n"
-  "#ifndef GLYPHY_TEXTURE1D_EXTRA_DECLS\n"
-  "#define GLYPHY_TEXTURE1D_EXTRA_DECLS\n"
-  "#endif\n"
-  "#ifndef GLYPHY_TEXTURE1D_EXTRA_ARGS\n"
-  "#define GLYPHY_TEXTURE1D_EXTRA_ARGS\n"
-  "#endif\n"
-  "\n"
-  "#ifndef GLYPHY_SDF_TEXTURE1D_FUNC\n"
-  "#define GLYPHY_SDF_TEXTURE1D_FUNC GLYPHY_TEXTURE1D_FUNC\n"
-  "#endif\n"
-  "#ifndef GLYPHY_SDF_TEXTURE1D_EXTRA_DECLS\n"
-  "#define GLYPHY_SDF_TEXTURE1D_EXTRA_DECLS GLYPHY_TEXTURE1D_EXTRA_DECLS\n"
-  "#endif\n"
-  "#ifndef GLYPHY_SDF_TEXTURE1D_EXTRA_ARGS\n"
-  "#define GLYPHY_SDF_TEXTURE1D_EXTRA_ARGS GLYPHY_TEXTURE1D_EXTRA_ARGS\n"
-  "#endif\n"
-  "#ifndef GLYPHY_SDF_TEXTURE1D\n"
-  "#define GLYPHY_SDF_TEXTURE1D(offset) GLYPHY_RGBA(GLYPHY_SDF_TEXTURE1D_FUNC (offset GLYPHY_TEXTURE1D_EXTRA_ARGS))\n"
-  "#endif\n"
-  "\n"
-  "#ifndef GLYPHY_MAX_NUM_ENDPOINTS\n"
-  "#define GLYPHY_MAX_NUM_ENDPOINTS 32\n"
-  "#endif\n"
-  "\n"
-  "glyphy_arc_list_t\n"
-  "glyphy_arc_list (const vec2 p, const ivec2 nominal_size GLYPHY_SDF_TEXTURE1D_EXTRA_DECLS)\n"
-  "{\n"
-  "  int cell_offset = glyphy_arc_list_offset (p, nominal_size);\n"
-  "  vec4 arc_list_data = GLYPHY_SDF_TEXTURE1D (cell_offset);\n"
-  "  return glyphy_arc_list_decode (arc_list_data, nominal_size);\n"
-  "}\n"
-  "\n"
-  "float\n"
-  "glyphy_sdf (const vec2 p, const ivec2 nominal_size GLYPHY_SDF_TEXTURE1D_EXTRA_DECLS)\n"
-  "{\n"
-  "  glyphy_arc_list_t arc_list = glyphy_arc_list (p, nominal_size  GLYPHY_SDF_TEXTURE1D_EXTRA_ARGS);\n"
-  "\n"
-  "  /* Short-circuits */\n"
-  "  if (arc_list.num_endpoints == 0) {\n"
-  "    /* far-away cell */\n"
-  "    return GLYPHY_INFINITY * float(arc_list.side);\n"
-  "  } if (arc_list.num_endpoints == -1) {\n"
-  "    /* single-line */\n"
-  "    float angle = arc_list.line_angle;\n"
-  "    vec2 n = vec2 (cos (angle), sin (angle));\n"
-  "    return dot (p - (vec2(nominal_size) * .5), n) - arc_list.line_distance;\n"
-  "  }\n"
-  "\n"
-  "  float side = float(arc_list.side);\n"
-  "  float min_dist = GLYPHY_INFINITY;\n"
-  "  glyphy_arc_t closest_arc;\n"
-  "\n"
-  "  glyphy_arc_endpoint_t endpoint_prev, endpoint;\n"
-  "  endpoint_prev = glyphy_arc_endpoint_decode (GLYPHY_SDF_TEXTURE1D (arc_list.offset), nominal_size);\n"
-  "  for (int i = 1; i < GLYPHY_MAX_NUM_ENDPOINTS; i++)\n"
-  "  {\n"
-  "    if (i >= arc_list.num_endpoints) {\n"
-  "      break;\n"
-  "    }\n"
-  "    endpoint = glyphy_arc_endpoint_decode (GLYPHY_SDF_TEXTURE1D (arc_list.offset + i), nominal_size);\n"
-  "    glyphy_arc_t a = glyphy_arc_t (endpoint_prev.p, endpoint.p, endpoint.d);\n"
-  "    endpoint_prev = endpoint;\n"
-  "    if (glyphy_isinf (a.d)) continue;\n"
-  "\n"
-  "    if (glyphy_arc_wedge_contains (a, p))\n"
-  "    {\n"
-  "      float sdist = glyphy_arc_wedge_signed_dist (a, p);\n"
-  "      float udist = abs (sdist) * (1. - GLYPHY_EPSILON);\n"
-  "      if (udist <= min_dist) {\n"
-  "       min_dist = udist;\n"
-  "       side = sign (sdist);"
-  "      }\n"
-  "    } else {\n"
-  "      float udist = min (distance (p, a.p0), distance (p, a.p1));\n"
-  "      if (udist < min_dist) {\n"
-  "       min_dist = udist;\n"
-  "       side = 0.; /* unsure */\n"
-  "       closest_arc = a;\n"
-  "      } else if (side == 0. && udist == min_dist) {\n"
-  "       /* If this new distance is the same as the current minimum,\n"
-  "        * compare extended distances.  Take the sign from the arc\n"
-  "        * with larger extended distance. */\n"
-  "       float old_ext_dist = glyphy_arc_extended_dist (closest_arc, p);\n"
-  "       float new_ext_dist = glyphy_arc_extended_dist (a, p);\n"
-  "\n"
-  "       float ext_dist = abs (new_ext_dist) <= abs (old_ext_dist) ?\n"
-  "                        old_ext_dist : new_ext_dist;\n"
-  "\n"
-  "#ifdef GLYPHY_SDF_PSEUDO_DISTANCE\n"
-  "       /* For emboldening and stuff: */\n"
-  "       min_dist = abs (ext_dist);\n"
-  "#endif\n"
-  "       side = sign (ext_dist);\n"
-  "      }\n"
-  "    }\n"
-  "  }\n"
-  "\n"
-  "  if (side == 0.) {\n"
-  "    // Technically speaking this should not happen, but it does.  So try to fix it.\n"
-  "    float ext_dist = glyphy_arc_extended_dist (closest_arc, p);\n"
-  "    side = sign (ext_dist);\n"
-  "  }\n"
-  "\n"
-  "  return min_dist * side;\n"
-  "}\n"
-  "\n"
-  "float\n"
-  "glyphy_point_dist (const vec2 p, const ivec2 nominal_size GLYPHY_SDF_TEXTURE1D_EXTRA_DECLS)\n"
-  "{\n"
-  "  glyphy_arc_list_t arc_list = glyphy_arc_list (p, nominal_size  GLYPHY_SDF_TEXTURE1D_EXTRA_ARGS);\n"
-  "\n"
-  "  float side = float(arc_list.side);\n"
-  "  float min_dist = GLYPHY_INFINITY;\n"
-  "\n"
-  "  if (arc_list.num_endpoints == 0)\n"
-  "    return min_dist;\n"
-  "\n"
-  "  glyphy_arc_endpoint_t endpoint;\n"
-  "  for (int i = 0; i < GLYPHY_MAX_NUM_ENDPOINTS; i++)\n"
-  "  {\n"
-  "    if (i >= arc_list.num_endpoints) {\n"
-  "      break;\n"
-  "    }\n"
-  "    endpoint = glyphy_arc_endpoint_decode (GLYPHY_SDF_TEXTURE1D (arc_list.offset + i), nominal_size);\n"
-  "    if (glyphy_isinf (endpoint.d)) continue;\n"
-  "    min_dist = min (min_dist, distance (p, endpoint.p));\n"
-  "  }\n"
-  "  return min_dist;\n"
-  "}\n";
index 4be2524..6ff571a 100644 (file)
 #include <sstream>
 
 // INTERNAL INCLUDES
-#include <dali-toolkit/internal/text/rendering/vector-based/glyphy-shader/glyphy-common-glsl.h>
-#include <dali-toolkit/internal/text/rendering/vector-based/glyphy-shader/glyphy-sdf-glsl.h>
+#include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
 
 using namespace Dali;
 
-namespace
-{
-const char* const ENABLE_EXTENSION_PREFIX =
-  "#extension GL_OES_standard_derivatives : enable\n"
-  "precision highp float;\n"
-  "precision highp int;\n";
-
-const char* const VERTEX_SHADER_MAIN =
-  "uniform   mediump mat4    uProjection;\n"
-  "uniform   mediump mat4    uModelView;\n"
-  "uniform   mediump mat4    uMvpMatrix;\n"
-  "uniform           bool    uTextureMapped;\n"
-  "uniform   mediump vec4    uCustomTextureCoords;\n"
-  "attribute highp   vec2    aTexCoord;\n"
-  "varying   mediump vec2    vTexCoord;\n"
-  "uniform   mat3            uModelViewIT;\n"
-  "attribute mediump vec3    aNormal;\n"
-  "varying   mediump vec3    vNormal;\n"
-  "attribute mediump vec2    aPosition;\n"
-  "varying   mediump vec4    vVertex;\n"
-  "attribute mediump vec4    aColor;\n"
-  "varying   mediump vec4    vColor;\n"
-  "varying vec4 v_glyph;\n"
-  "\n"
-  "vec4\n"
-  "glyph_vertex_transcode (vec2 v)\n"
-  "{\n"
-  "  ivec2 g = ivec2 (v);\n"
-  "  ivec2 corner = ivec2 (mod (v, 2.));\n"
-  "  g /= 2;\n"
-  "  ivec2 nominal_size = ivec2 (mod (vec2(g), 64.));\n"
-  "  return vec4 (corner * nominal_size, g * 4);\n"
-  "}\n"
-  "\n"
-  "void\n"
-  "main()\n"
-  "{\n"
-  "  gl_Position = uMvpMatrix * vec4 (aPosition, 0.0, 1.0);\n"
-  "  v_glyph = glyph_vertex_transcode (aTexCoord);\n"
-  "  vColor = aColor;\n"
-  "}\n";
-
-const char* const FRAGMENT_SHADER_PREFIX =
-  "struct Material\n"
-  "{\n"
-  "  mediump float mOpacity;\n"
-  "  mediump float mShininess;\n"
-  "  lowp    vec4  mAmbient;\n"
-  "  lowp    vec4  mDiffuse;\n"
-  "  lowp    vec4  mSpecular;\n"
-  "  lowp    vec4  mEmissive;\n"
-  "};\n"
-  "uniform sampler2D     sTexture;\n"
-  "uniform sampler2D     sOpacityTexture;\n"
-  "uniform sampler2D     sNormalMapTexture;\n"
-  "uniform sampler2D     sEffect;\n"
-  "varying mediump vec2 vTexCoord;\n"
-  "uniform Material      uMaterial;\n"
-  "uniform lowp  vec4    uColor;\n"
-  "varying highp vec4    vVertex;\n"
-  "varying highp vec3    vNormal;\n"
-  "varying mediump vec4  vColor;\n"
-  "uniform vec4 u_atlas_info;\n"
-  "\n"
-  "#define GLYPHY_TEXTURE1D_EXTRA_DECLS , sampler2D _tex, ivec4 _atlas_info, ivec2 _atlas_pos\n"
-  "#define GLYPHY_TEXTURE1D_EXTRA_ARGS , _tex, _atlas_info, _atlas_pos\n"
-  "#define GLYPHY_DEMO_EXTRA_ARGS , sTexture, uu_atlas_info, gi.atlas_pos\n"
-  "\n"
-  "vec4\n"
-  "glyphy_texture1D_func (int offset GLYPHY_TEXTURE1D_EXTRA_DECLS)\n"
-  "{\n"
-  "  ivec2 item_geom = _atlas_info.zw;\n"
-  "  vec2 pos = (vec2 (_atlas_pos.xy * item_geom +\n"
-  "                    ivec2 (mod (float (offset), float (item_geom.x)), offset / item_geom.x)) +\n"
-  "             + vec2 (.5, .5)) / vec2(_atlas_info.xy);\n"
-  "  return texture2D (_tex, pos);\n"
-  "}\n";
-
-static const char* FRAGMENT_SHADER_MAIN =
-  "uniform float u_contrast;\n"
-  "uniform float u_gamma_adjust;\n"
-  "uniform float u_outline_thickness;\n"
-  "uniform float u_outline;\n"
-  "uniform float u_boldness;\n"
-  "\n"
-  "varying vec4 v_glyph;\n"
-  "\n"
-  "\n"
-  "#define SQRT2_2 0.70711 /* 1 / sqrt(2.) */\n"
-  "#define SQRT2   1.41421\n"
-  "\n"
-  "struct glyph_info_t {\n"
-  "  ivec2 nominal_size;\n"
-  "  ivec2 atlas_pos;\n"
-  "};\n"
-  "\n"
-  "glyph_info_t\n"
-  "glyph_info_decode (vec4 v)\n"
-  "{\n"
-  "  glyph_info_t gi;\n"
-  "  gi.nominal_size = (ivec2 (mod (v.zw, 256.)) + 2) / 4;\n"
-  "  gi.atlas_pos = ivec2 (v_glyph.zw) / 256;\n"
-  "  return gi;\n"
-  "}\n"
-  "\n"
-  "\n"
-  "float\n"
-  "antialias (float d)\n"
-  "{\n"
-  "  return smoothstep (-.75, +.75, d);\n"
-  "}\n"
-  "\n"
-  "vec4\n"
-  "source_over (const vec4 src, const vec4 dst)\n"
-  "{\n"
-  "  // http://dev.w3.org/fxtf/compositing-1/#porterduffcompositingoperators_srcover\n"
-  "  float alpha = src.a + (dst.a * (1. - src.a));\n"
-  "  return vec4 (((src.rgb * src.a) + (dst.rgb * dst.a * (1. - src.a))) / alpha, alpha);\n"
-  "}\n"
-  "\n"
-  "void\n"
-  "main()\n"
-  "{\n"
-  "  vec2 p = v_glyph.xy;\n"
-  "  glyph_info_t gi = glyph_info_decode (v_glyph);\n"
-  "\n"
-  "  /* isotropic antialiasing */\n"
-  "  vec2 dpdx = dFdx (p);\n"
-  "  vec2 dpdy = dFdy (p);\n"
-  "  float m = length (vec2 (length (dpdx), length (dpdy))) * SQRT2_2;\n"
-  "\n"
-  "  vec4 color = vec4( vColor.rgb * uColor.rgb, vColor.a * uColor.a );\n"
-  "\n"
-  "  ivec4 uu_atlas_info = ivec4( u_atlas_info );"
-  "  float gsdist = glyphy_sdf (p, gi.nominal_size GLYPHY_DEMO_EXTRA_ARGS);\n"
-  "  float sdist = gsdist / m * u_contrast;\n"
-  "\n"
-  "    sdist -= u_boldness * 10.;\n"
-  "    if ( glyphy_iszero( u_outline ) )\n"
-  "      sdist = abs (sdist) - u_outline_thickness * .5;\n"
-  "    if (sdist > 1.)\n"
-  "      discard;\n"
-  "    float alpha = antialias (-sdist);\n"
-  "    if (u_gamma_adjust != 1.)\n"
-  "      alpha = pow (alpha, 1./u_gamma_adjust);\n"
-  "    color = vec4 (color.rgb,color.a * alpha);\n"
-  "\n"
-  "  gl_FragColor = color;\n"
-  "}\n";
-
-} // namespace
-
 namespace Dali
 {
 namespace Toolkit
@@ -203,14 +50,14 @@ GlyphyShader GlyphyShader::New(const Dali::Vector4& atlasInfo)
   std::ostringstream vertexShaderStringStream;
   std::ostringstream fragmentShaderStringStream;
 
-  vertexShaderStringStream << ENABLE_EXTENSION_PREFIX << VERTEX_SHADER_MAIN;
+  vertexShaderStringStream << SHADER_GLYPHY_SHADER_EXTENTION_PREFIX_DEF.data() << SHADER_GLYPHY_SHADER_MAIN_VERT.data();
 
-  fragmentShaderStringStream << ENABLE_EXTENSION_PREFIX
-                             << FRAGMENT_SHADER_PREFIX
-                             << glyphy_common_glsl
+  fragmentShaderStringStream << SHADER_GLYPHY_SHADER_EXTENTION_PREFIX_DEF.data()
+                             << SHADER_GLYPHY_SHADER_FRAGMENT_PREFIX_FRAG.data()
+                             << SHADER_GLYPHY_COMMON_GLSL_SHADER_DEF.data()
                              << "#define GLYPHY_SDF_PSEUDO_DISTANCE 1\n"
-                             << glyphy_sdf_glsl
-                             << FRAGMENT_SHADER_MAIN;
+                             << SHADER_GLYPHY_SDF_GLSL_SHADER_DEF.data()
+                             << SHADER_GLYPHY_SHADER_MAIN_FRAG.data();
 
   Shader shaderEffectCustom = Shader::New(vertexShaderStringStream.str(),
                                           fragmentShaderStringStream.str(),
index 2ad03c5..f695cd2 100644 (file)
@@ -230,6 +230,21 @@ bool ViewModel::IsMarkupProcessorEnabled() const
   return mModel->IsMarkupProcessorEnabled();
 }
 
+const GlyphInfo* ViewModel::GetHyphens() const
+{
+  return mModel->GetHyphens();
+}
+
+const Length* ViewModel::GetHyphenIndices() const
+{
+  return mModel->GetHyphenIndices();
+}
+
+Length ViewModel::GetHyphensCount() const
+{
+  return mModel->GetHyphensCount();
+}
+
 void ViewModel::ElideGlyphs()
 {
   mIsTextElided = false;
index 1ea38ee..9272956 100644 (file)
@@ -216,6 +216,21 @@ public:
   bool IsMarkupProcessorEnabled() const override;
 
   /**
+  * @copydoc ModelInterface::GetHyphens()
+  */
+  const GlyphInfo* GetHyphens() const override;
+
+  /**
+  * @copydoc ModelInterface::GetHyphens()
+  */
+  const Length* GetHyphenIndices() const override;
+
+  /**
+  * @copydoc ModelInterface::GetHyphens()
+  */
+  Length GetHyphensCount() const override;
+
+  /**
    * @brief Does the text elide.
    *
    * It stores a copy of the visible glyphs and removes as many glyphs as needed
index 2faaee1..417eaed 100644 (file)
@@ -29,6 +29,7 @@
 #include <dali-toolkit/internal/text/character-set-conversion.h>
 #include <dali-toolkit/internal/text/color-segmentation.h>
 #include <dali-toolkit/internal/text/cursor-helper-functions.h>
+#include <dali-toolkit/internal/text/hyphenator.h>
 #include <dali-toolkit/internal/text/multi-language-support.h>
 #include <dali-toolkit/internal/text/segmentation.h>
 #include <dali-toolkit/internal/text/shaper.h>
@@ -37,6 +38,8 @@
 #include <dali-toolkit/internal/text/text-run-container.h>
 #include <dali-toolkit/internal/text/text-selection-handle-controller.h>
 
+#include <dali-toolkit/internal/text/text-enumerations-impl.h>
+
 using namespace Dali;
 
 namespace
@@ -661,6 +664,39 @@ bool Controller::Impl::UpdateModel(OperationsMask operationsRequired)
                      requestedNumberOfCharacters,
                      lineBreakInfo);
 
+    if(mModel->mLineWrapMode == ((Text::LineWrap::Mode)DevelText::LineWrap::HYPHENATION) ||
+       mModel->mLineWrapMode == ((Text::LineWrap::Mode)DevelText::LineWrap::MIXED))
+    {
+      CharacterIndex end                 = startIndex + requestedNumberOfCharacters;
+      LineBreakInfo* lineBreakInfoBuffer = lineBreakInfo.Begin();
+
+      for(CharacterIndex index = startIndex; index < end; index++)
+      {
+        CharacterIndex wordEnd = index;
+        while((*(lineBreakInfoBuffer + wordEnd) != TextAbstraction::LINE_ALLOW_BREAK) && (*(lineBreakInfoBuffer + wordEnd) != TextAbstraction::LINE_MUST_BREAK))
+        {
+          wordEnd++;
+        }
+
+        if((wordEnd + 1) == end) // add last char
+        {
+          wordEnd++;
+        }
+
+        Vector<bool> hyphens = GetWordHyphens(utf32Characters.Begin() + index, wordEnd - index, nullptr);
+
+        for(CharacterIndex i = 0; i < (wordEnd - index); i++)
+        {
+          if(hyphens[i])
+          {
+            *(lineBreakInfoBuffer + index + i) = TextAbstraction::LINE_HYPHENATION_BREAK;
+          }
+        }
+
+        index = wordEnd;
+      }
+    }
+
     // Create the paragraph info.
     mModel->mLogicalModel->CreateParagraphInfo(startIndex,
                                                requestedNumberOfCharacters);
index 99c0264..6866ff4 100644 (file)
@@ -25,6 +25,7 @@
 #include <limits>
 
 // INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/text/text-enumerations-devel.h>
 #include <dali-toolkit/internal/text/text-controller-event-handler.h>
 #include <dali-toolkit/internal/text/text-controller-impl.h>
 #include <dali-toolkit/internal/text/text-controller-input-font-handler.h>
@@ -405,15 +406,22 @@ void Controller::SetLineWrapMode(Text::LineWrap::Mode lineWrapMode)
 {
   if(lineWrapMode != mImpl->mModel->mLineWrapMode)
   {
-    // Set the text wrap mode.
-    mImpl->mModel->mLineWrapMode = lineWrapMode;
-
     // Update Text layout for applying wrap mode
-    mImpl->mOperationsPending                          = static_cast<OperationsMask>(mImpl->mOperationsPending |
+    mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending |
                                                             ALIGN |
                                                             LAYOUT |
                                                             UPDATE_LAYOUT_SIZE |
                                                             REORDER);
+
+    if((mImpl->mModel->mLineWrapMode == (Text::LineWrap::Mode)DevelText::LineWrap::HYPHENATION) || (lineWrapMode == (Text::LineWrap::Mode)DevelText::LineWrap::HYPHENATION) ||
+       (mImpl->mModel->mLineWrapMode == (Text::LineWrap::Mode)DevelText::LineWrap::MIXED) || (lineWrapMode == (Text::LineWrap::Mode)DevelText::LineWrap::MIXED)) // hyphen is treated as line break
+    {
+      mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | GET_LINE_BREAKS);
+    }
+
+    // Set the text wrap mode.
+    mImpl->mModel->mLineWrapMode = lineWrapMode;
+
     mImpl->mTextUpdateInfo.mCharacterIndex             = 0u;
     mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters;
     mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd    = mImpl->mModel->mLogicalModel->mText.Count();
index 5c3fa1f..c116f8f 100644 (file)
@@ -272,6 +272,27 @@ public:
    * @return The markup-processor state.
    */
   virtual bool IsMarkupProcessorEnabled() const = 0;
+
+  /**
+   * @brief Returns the hyphens glyph info.
+   *
+   * @return hyphens glyph info.
+   */
+  virtual const GlyphInfo* GetHyphens() const = 0;
+
+  /**
+   * @brief Returns the indices of the hyphen in the text.
+   *
+   * @return the hyphen indices.
+   */
+  virtual const Length* GetHyphenIndices() const = 0;
+
+  /**
+   * @brief Returns number of hyphens to add in text.
+   *
+   * @return number of hyphens.
+   */
+  virtual Length GetHyphensCount() const = 0;
 };
 
 } // namespace Text
index 42a5795..948044e 100644 (file)
@@ -189,6 +189,21 @@ bool Model::IsMarkupProcessorEnabled() const
   return mVisualModel->IsMarkupProcessorEnabled();
 }
 
+const GlyphInfo* Model::GetHyphens() const
+{
+  return mVisualModel->mHyphen.glyph.Begin();
+}
+
+const Length* Model::GetHyphenIndices() const
+{
+  return mVisualModel->mHyphen.index.Begin();
+}
+
+Length Model::GetHyphensCount() const
+{
+  return mVisualModel->mHyphen.glyph.Size();
+}
+
 Model::Model()
 : mLogicalModel(),
   mVisualModel(),
index 705adeb..4faa1bc 100644 (file)
@@ -212,6 +212,21 @@ public:
    */
   bool IsMarkupProcessorEnabled() const override;
 
+  /**
+  * @copydoc ModelInterface::GetHyphens()
+  */
+  const GlyphInfo* GetHyphens() const override;
+
+  /**
+  * @copydoc ModelInterface::GetHyphens()
+  */
+  const Length* GetHyphenIndices() const override;
+
+  /**
+  * @copydoc ModelInterface::GetHyphens()
+  */
+  Length GetHyphensCount() const override;
+
 private: // Private contructors & copy operator.
   /**
    * @brief Private constructor.
index 1a04135..63f7fd4 100644 (file)
@@ -159,6 +159,26 @@ public:
   virtual bool IsUnderlineEnabled() const = 0;
 
   /**
+   * @brief Returns the hyphens glyph info.
+   *
+   * @return hyphens glyph info.
+   */
+  virtual const GlyphInfo* GetHyphens() const = 0;
+
+  /**
+   * @brief Returns the indices of the hyphen in the text.
+   *
+   * @return the hyphen indices.
+   */
+  virtual const Length* GetHyphenIndices() const = 0;
+
+  /**
+   * @brief Returns number of hyphens to add in text.
+   *
+   * @return number of hyphens.
+   */
+  virtual Length GetHyphensCount() const = 0;
+  /**
    * @brief Retrieves the underline height override
    *
    * @return Returns the override height for an underline, 0 indicates that adaptor will determine the height
index 83ad28f..2f74699 100644 (file)
@@ -388,6 +388,35 @@ bool View::IsUnderlineEnabled() const
   return false;
 }
 
+const GlyphInfo* View::GetHyphens() const
+{
+  if(mImpl->mVisualModel)
+  {
+    return mImpl->mVisualModel->mHyphen.glyph.Begin();
+  }
+
+  return nullptr;
+}
+
+const Length* View::GetHyphenIndices() const
+{
+  if(mImpl->mVisualModel)
+  {
+    return mImpl->mVisualModel->mHyphen.index.Begin();
+  }
+
+  return nullptr;
+}
+
+Length View::GetHyphensCount() const
+{
+  if(mImpl->mVisualModel)
+  {
+    return mImpl->mVisualModel->mHyphen.glyph.Size();
+  }
+
+  return 0;
+}
 float View::GetUnderlineHeight() const
 {
   if(mImpl->mVisualModel)
index cc82820..3790fd0 100644 (file)
@@ -121,6 +121,21 @@ public:
   bool IsUnderlineEnabled() const override;
 
   /**
+  * @copydoc Dali::Toolkit::Text::ViewInterface::GetHyphens()
+  */
+  const GlyphInfo* GetHyphens() const override;
+
+  /**
+  * @copydoc Dali::Toolkit::Text::ViewInterface::GetHyphens()
+  */
+  const Length* GetHyphenIndices() const override;
+
+  /**
+  * @copydoc Dali::Toolkit::Text::ViewInterface::GetHyphens()
+  */
+  Length GetHyphensCount() const override;
+
+  /**
    * @copydoc Dali::Toolkit::Text::ViewInterface::GetUnderlineHeight()
    */
   float GetUnderlineHeight() const override;
index bf3ead2..c355c3c 100644 (file)
@@ -35,6 +35,13 @@ namespace Toolkit
 {
 namespace Text
 {
+struct HyphenInfo
+{
+  Vector<GlyphInfo> glyph;
+  Vector<Vector2>   position;
+  Vector<Length>    index;
+};
+
 class VisualModel;
 typedef IntrusivePtr<VisualModel> VisualModelPtr;
 
@@ -422,6 +429,7 @@ public:
   bool mUnderlineColorSet : 1; ///< Has the underline color been explicitly set?
   bool mBackgroundEnabled : 1; ///< Background enabled flag
   bool mMarkupProcessorEnabled : 1; ///< Markup-processor enabled flag
+  HyphenInfo mHyphen; ///< Contains hyphen glyph info & the character index to draw hyphen after.
 };
 
 } // namespace Text
index 048eae4..c3e32cb 100644 (file)
@@ -29,7 +29,7 @@ namespace Toolkit
 {
 const unsigned int TOOLKIT_MAJOR_VERSION = 2;
 const unsigned int TOOLKIT_MINOR_VERSION = 0;
-const unsigned int TOOLKIT_MICRO_VERSION = 24;
+const unsigned int TOOLKIT_MICRO_VERSION = 25;
 const char* const  TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index 8feb0e8..94d8e11 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali2-toolkit
 Summary:    Dali 3D engine Toolkit
-Version:    2.0.24
+Version:    2.0.25
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT