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)
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)
+
-#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);
}
--- /dev/null
+/*
+ * 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;
+}
utc-Dali-Visuals-internal.cpp
utc-Dali-VisualModel.cpp
utc-Dali-VisualUrl.cpp
+ utc-Dali-Text-Hyphen-Wrapping.cpp
)
IF(ELDBUS_AVAILABLE)
/*
- * 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.
#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
{
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;
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();
// Set the layout parameters.
textModel->mHorizontalAlignment = Text::HorizontalAlignment::BEGIN;
- textModel->mLineWrapMode = LineWrap::WORD;
textModel->mIgnoreSpacesAfterText = true;
textModel->mMatchSystemLanguageDirection = false;
Layout::Parameters layoutParameters( textArea,
#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.
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.
/*
- * 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.
layoutSize,
textModel,
metrics,
- false );
+ false,
+ LineWrap::WORD );
LogicalModelPtr logicalModel = textModel->mLogicalModel;
VisualModelPtr visualModel = textModel->mVisualModel;
layoutSize,
textModel,
metrics,
- false );
+ false,
+ LineWrap::WORD );
LogicalModelPtr logicalModel = textModel->mLogicalModel;
VisualModelPtr visualModel = textModel->mVisualModel;
layoutSize,
textModel,
metrics,
- data.markupProcessorEnabled );
+ data.markupProcessorEnabled,
+ LineWrap::WORD );
LogicalModelPtr logicalModel = textModel->mLogicalModel;
VisualModelPtr visualModel = textModel->mVisualModel;
/*
- * 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.
layoutSize,
textModel,
metrics,
- false );
+ false,
+ LineWrap::WORD );
LogicalModelPtr logicalModel = textModel->mLogicalModel;
VisualModelPtr visualModel = textModel->mVisualModel;
layoutSize,
textModel,
metrics,
- false );
+ false,
+ LineWrap::WORD );
LogicalModelPtr logicalModel = textModel->mLogicalModel;
VisualModelPtr visualModel = textModel->mVisualModel;
layoutSize,
textModel,
metrics,
- false );
+ false,
+ LineWrap::WORD );
LogicalModelPtr logicalModel = textModel->mLogicalModel;
VisualModelPtr visualModel = textModel->mVisualModel;
layoutSize,
textModel,
metrics,
- false );
+ false,
+ LineWrap::WORD );
LogicalModelPtr logicalModel = textModel->mLogicalModel;
VisualModelPtr visualModel = textModel->mVisualModel;
layoutSize,
textModel,
metrics,
- false );
+ false,
+ LineWrap::WORD );
LogicalModelPtr logicalModel = textModel->mLogicalModel;
VisualModelPtr visualModel = textModel->mVisualModel;
/*
- * 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.
layoutSize,
textModel,
metrics,
- false );
+ false,
+ LineWrap::WORD );
LogicalModelPtr logicalModel = textModel->mLogicalModel;
VisualModelPtr visualModel = textModel->mVisualModel;
layoutSize,
textModel,
metrics,
- false );
+ false,
+ LineWrap::WORD );
LogicalModelPtr logicalModel = textModel->mLogicalModel;
VisualModelPtr visualModel = textModel->mVisualModel;
layoutSize,
textModel,
metrics,
- false );
+ false,
+ LineWrap::WORD );
LogicalModelPtr logicalModel = textModel->mLogicalModel;
VisualModelPtr visualModel = textModel->mVisualModel;
layoutSize,
textModel,
metrics,
- false );
+ false,
+ LineWrap::WORD );
LogicalModelPtr logicalModel = textModel->mLogicalModel;
VisualModelPtr visualModel = textModel->mVisualModel;
--- /dev/null
+/*
+ * 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
/*
- * 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.
layoutSize,
textModel,
metrics,
- false );
+ false,
+ LineWrap::WORD );
LogicalModelPtr logicalModel = textModel->mLogicalModel;
VisualModelPtr visualModel = textModel->mVisualModel;
layoutSize,
textModel,
metrics,
- false );
+ false,
+ LineWrap::WORD );
LogicalModelPtr logicalModel = textModel->mLogicalModel;
VisualModelPtr visualModel = textModel->mVisualModel;
/*
- * 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.
layoutSize,
textModel,
metrics,
- false );
+ false,
+ LineWrap::WORD );
LogicalModelPtr logicalModel = textModel->mLogicalModel;
VisualModelPtr visualModel = textModel->mVisualModel;
/*
- * 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.
layoutSize,
textModel,
metrics,
- false );
+ false,
+ LineWrap::WORD );
LogicalModelPtr logicalModel = textModel->mLogicalModel;
VisualModelPtr visualModel = textModel->mVisualModel;
layoutSize,
textModel,
metrics,
- false );
+ false,
+ LineWrap::WORD );
LogicalModelPtr logicalModel = textModel->mLogicalModel;
VisualModelPtr visualModel = textModel->mVisualModel;
Dali::PixelData GetImageBuffer() override
{
- uint8_t* faviconData = new uint8_t[ 16 ];
- memset(faviconData, 0xff, 16);
- return Dali::PixelData::New( faviconData, 16, 2, 2,
- Dali::Pixel::Format::RGBA8888,
- Dali::PixelData::ReleaseFunction::DELETE_ARRAY );
+ uint8_t* imageData = new uint8_t[16];
+ memset(imageData, 0xff, 16);
+ return Dali::PixelData::New(imageData, 16, 2, 2,
+ Dali::Pixel::Format::RGBA8888,
+ Dali::PixelData::ReleaseFunction::DELETE_ARRAY);
}
private:
Dali::PixelData GetFavicon() const
{
- uint8_t* faviconData = new uint8_t[ 16 ];
-
- faviconData[ 0 ] = 0xff;
- faviconData[ 1 ] = 0x00;
- faviconData[ 2 ] = 0x00;
- faviconData[ 3 ] = 0xff;
- faviconData[ 4 ] = 0xff;
- faviconData[ 5 ] = 0x00;
- faviconData[ 6 ] = 0x00;
- faviconData[ 7 ] = 0xff;
- faviconData[ 8 ] = 0xff;
- faviconData[ 9 ] = 0x00;
- faviconData[ 10 ] = 0x00;
- faviconData[ 11 ] = 0xff;
- faviconData[ 12 ] = 0xff;
- faviconData[ 13 ] = 0x00;
- faviconData[ 14 ] = 0x00;
- faviconData[ 15 ] = 0xff;
-
- return Dali::PixelData::New( faviconData, 16, 2, 2,
- Dali::Pixel::Format::RGBA8888,
- Dali::PixelData::ReleaseFunction::DELETE_ARRAY );
+ static int testGetFaviconCount = 0;
+ if (testGetFaviconCount == 0)
+ {
+ testGetFaviconCount++;
+ uint8_t* faviconData = new uint8_t[16];
+ memset(faviconData, 0xff, 16);
+ return Dali::PixelData::New(faviconData, 16, 2, 2,
+ Dali::Pixel::Format::RGBA8888,
+ Dali::PixelData::ReleaseFunction::DELETE_ARRAY);
+ }
+ else
+ {
+ return Dali::PixelData();
+ }
}
bool CanGoForward() const
const char* TEST_VECTOR_IMAGE_FILE_NAME_FRAME_DROP = "framedrop.json";
const char* TEST_VECTOR_IMAGE_INVALID_FILE_NAME = "invalid.json";
-const char* TEST_VECTOR_IMAGE_RIVE_FILE_NAME = TEST_RESOURCE_DIR "/juice.riv";
+const char* TEST_VECTOR_IMAGE_RIVE_FILE_NAME = TEST_RESOURCE_DIR "/shape.riv";
const char* TEST_VECTOR_IMAGE_INVALID_RIVE_FILE_NAME = "invalid.riv";
bool gAnimationFinishedSignalFired = false;
#include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
#include <dali-toolkit/devel-api/controls/control-devel.h>
#include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
+#include <dali-toolkit/public-api/image-loader/image.h>
#include <dali-toolkit/dali-toolkit.h>
#include "dummy-control.h"
END_TEST;
}
+
+int UtcDaliImageVisualWithNativeImage(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline( "Use Native Image as url" );
+
+ NativeImageSourcePtr nativeImageSource = NativeImageSource::New(500, 500, NativeImageSource::COLOR_DEPTH_DEFAULT);
+ std::string url = Dali::Toolkit::Image::GenerateUrl(nativeImageSource);
+
+ VisualFactory factory = VisualFactory::Get();
+ DALI_TEST_CHECK( factory );
+
+ Property::Map propertyMap;
+ propertyMap.Insert( Toolkit::Visual::Property::TYPE, Visual::IMAGE );
+ propertyMap.Insert( ImageVisual::Property::URL, url );
+
+ Visual::Base visual = factory.CreateVisual( propertyMap );
+ DALI_TEST_CHECK( visual );
+
+ DummyControl actor = DummyControl::New();
+ DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+ dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
+
+ DALI_TEST_EQUALS( actor.GetRendererCount(), 0u, TEST_LOCATION );
+
+ application.GetScene().Add( actor );
+
+ DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION );
+
+ Renderer renderer = actor.GetRendererAt(0);
+ Shader shader = renderer.GetShader();
+
+ Property::Value value = shader.GetProperty(Shader::Property::PROGRAM);
+ DALI_TEST_CHECK(value.GetType() == Property::MAP);
+ const Property::Map* outMap = value.GetMap();
+ std::string fragmentShader = (*outMap)["fragment"].Get<std::string>();
+
+ const char* fragmentPrefix = nativeImageSource->GetCustomFragmentPrefix();
+ size_t pos = fragmentShader.find(fragmentPrefix);
+
+ DALI_TEST_EQUALS( pos != std::string::npos, true, TEST_LOCATION );
+
+ END_TEST;
+}
+
int UtcDaliImageVisualTextureReuse1(void)
{
ToolkitTestApplication application;
#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;
}
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
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;
+}
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;
view.GetProperty( WebView::Property::TITLE ).Get( output );
DALI_TEST_EQUALS( output, testValue, TEST_LOCATION );
- // Check default value of favicon
- Dali::Toolkit::ImageView* favicon = &view.GetFavicon();
+ // Check the case that favicon is not null.
+ Dali::Toolkit::ImageView favicon = view.GetFavicon();
DALI_TEST_CHECK( favicon );
- Dali::Vector3 iconsize = favicon->GetProperty< Vector3 >( Dali::Actor::Property::SIZE );
+ Dali::Vector3 iconsize = favicon.GetProperty< Vector3 >( Dali::Actor::Property::SIZE );
DALI_TEST_CHECK( ( int )iconsize.width == 2 && ( int )iconsize.height == 2 );
+ // Check the case that favicon is null.
+ favicon = view.GetFavicon();
+ DALI_TEST_CHECK( !favicon );
+
END_TEST;
}
return Dali::Toolkit::GetImpl(*this).GetBackForwardList();
}
-Dali::Toolkit::ImageView& WebView::GetFavicon()
+Dali::Toolkit::ImageView WebView::GetFavicon() const
{
return Dali::Toolkit::GetImpl(*this).GetFavicon();
}
Dali::Toolkit::WebBackForwardList* GetBackForwardList() const;
/**
- * @brief Get Favicon of web page.
+ * @brief Get favicon of web page.
*
- * @return Handle to a fav icon
+ * @return Handle to a favicon
*/
- Dali::Toolkit::ImageView& GetFavicon();
+ Dali::Toolkit::ImageView GetFavicon() const;
/**
* @brief Load a web page based on a given URL.
#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.
};
} // 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
// 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,
StopObservingVisual(iter->visual);
}
- AccessibilityDeregister(false);
// All gesture detectors will be destroyed so no need to disconnect.
delete mStartingPinchScale;
#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
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;
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);
return mWebBackForwardList.get();
}
-Dali::Toolkit::ImageView& WebView::GetFavicon()
+Dali::Toolkit::ImageView WebView::GetFavicon() const
{
+ Dali::Toolkit::ImageView faviconView;
if(mWebEngine)
{
Dali::PixelData pixelData = mWebEngine.GetFavicon();
- mFaviconView = CreateImageView(pixelData);
+ faviconView = CreateImageView(pixelData);
}
- return mFaviconView;
+ return faviconView;
}
void WebView::LoadUrl(const std::string& url)
}
}
-Dali::Toolkit::ImageView WebView::CreateImageView(Dali::PixelData pixel)
+Dali::Toolkit::ImageView WebView::CreateImageView(Dali::PixelData pixel) const
{
+ if(!pixel)
+ {
+ return Dali::Toolkit::ImageView();
+ }
+
std::string url = Dali::Toolkit::Image::GenerateUrl(pixel);
Dali::Toolkit::ImageView imageView = Dali::Toolkit::ImageView::New(url);
imageView.SetProperty(Dali::Actor::Property::SIZE, Vector2(pixel.GetWidth(), pixel.GetHeight()));
/**
* @copydoc Dali::Toolkit::WebView::GetFavicon()
*/
- Dali::Toolkit::ImageView& GetFavicon();
+ Dali::Toolkit::ImageView GetFavicon() const;
/**
* @copydoc Dali::Toolkit::WebView::LoadUrl()
* @param[in] pixel Pixel data
* @return The new image view
*/
- Dali::Toolkit::ImageView CreateImageView(Dali::PixelData pixel);
+ Dali::Toolkit::ImageView CreateImageView(Dali::PixelData pixel) const;
/**
* @brief Callback function to be called when page load started.
std::unique_ptr<Dali::Toolkit::WebSettings> mWebSettings;
std::unique_ptr<Dali::Toolkit::WebBackForwardList> mWebBackForwardList;
- Dali::Toolkit::ImageView mFaviconView;
-
Dali::PropertyNotification mPositionUpdateNotification;
Dali::PropertyNotification mSizeUpdateNotification;
Dali::PropertyNotification mScaleUpdateNotification;
${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
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+#extension GL_OES_standard_derivatives : enable
+precision highp float;
+precision highp int;
--- /dev/null
+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);
+}
--- /dev/null
+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;
+}
--- /dev/null
+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
--- /dev/null
+/*
+ * 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
--- /dev/null
+#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
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)
{
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;
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;)
(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");
(TextAbstraction::LINE_MUST_BREAK == lineBreakInfo))
{
LineLayout currentLineLayout = lineLayout;
-
+ oneHyphenLaidOut = false;
// Must break the line. Update the line layout and return.
MergeLineLayout(lineLayout, tmpLineLayout);
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.
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;
}
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)
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;
}
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);
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.
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)
}
// 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
{
//Keep status of underlined for previous glyph to check consecutive indices
isPreUnderlined = isGlyphUnderlined;
}
+
+ if(addHyphen)
+ {
+ hyphenIndex++;
+ }
} // glyphs
// Now remove references for the old text
// Markup-Processor
imageBuffer = ApplyMarkupProcessorOnPixelBuffer(imageBuffer, bufferWidth, bufferHeight, ignoreHorizontalAlignment, pixelFormat, penX, penY);
-
}
// Create the final PixelData for the combined image buffer
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);
}
// 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)
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);
}
// 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))
} // underline
// Retrieves the glyph's position.
- const Vector2* const position = positionBuffer + glyphIndex;
- if(baseline < position->y + glyphInfo->yBearing)
+ Vector2 position = *(positionBuffer + glyphIndex);
+
+ if(addHyphen)
{
- baseline = position->y + glyphInfo->yBearing;
+ 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;
}
// 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.
// Set the buffer of the glyph's bitmap into the final bitmap's buffer
TypesetGlyph(glyphData,
- position,
+ &position,
&color,
style,
pixelFormat);
delete[] glyphData.glyphBitmap.buffer;
glyphData.glyphBitmap.buffer = NULL;
}
+
+ if(hyphenIndices)
+ {
+ while((hyphenIndex < hyphensCount) && (glyphIndex > hyphenIndices[hyphenIndex]))
+ {
+ hyphenIndex++;
+ }
+
+ addHyphen = ((hyphenIndex < hyphensCount) && ((glyphIndex + 1) == hyphenIndices[hyphenIndex]));
+ if(addHyphen)
+ {
+ glyphIndex--;
+ }
+ }
}
// Draw the underline from the leftmost glyph to the rightmost glyph
Devel::PixelBuffer Typesetter::ApplyMarkupProcessorOnPixelBuffer(Devel::PixelBuffer topPixelBuffer, const unsigned int bufferWidth, const unsigned int bufferHeight, bool ignoreHorizontalAlignment, Pixel::Format pixelFormat, int horizontalOffset, int verticalOffset)
{
- // Apply the markup-Processor if enabled
- const bool markupProcessorEnabled = mModel->IsMarkupProcessorEnabled();
- if(markupProcessorEnabled)
+ // Apply the markup-Processor if enabled
+ const bool markupProcessorEnabled = mModel->IsMarkupProcessorEnabled();
+ if(markupProcessorEnabled)
+ {
+ // Underline-tags (this is for Markup case)
+ // Get the underline runs.
+ const Length numberOfUnderlineRuns = mModel->GetNumberOfUnderlineRuns();
+ Vector<GlyphRun> underlineRuns;
+ underlineRuns.Resize(numberOfUnderlineRuns);
+ mModel->GetUnderlineRuns(underlineRuns.Begin(), 0u, numberOfUnderlineRuns);
+
+ // Iterate on the consecutive underlined glyph run and connect them into one chunk of underlined characters.
+ Vector<GlyphRun>::ConstIterator itGlyphRun = underlineRuns.Begin();
+ Vector<GlyphRun>::ConstIterator endItGlyphRun = underlineRuns.End();
+ GlyphIndex startGlyphIndex, endGlyphIndex;
+
+ //The outer loop to iterate on the separated chunks of underlined glyph runs
+ while(itGlyphRun != endItGlyphRun)
{
- // Underline-tags (this is for Markup case)
- // Get the underline runs.
- const Length numberOfUnderlineRuns = mModel->GetNumberOfUnderlineRuns();
- Vector<GlyphRun> underlineRuns;
- underlineRuns.Resize(numberOfUnderlineRuns);
- mModel->GetUnderlineRuns(underlineRuns.Begin(), 0u, numberOfUnderlineRuns);
-
- // Iterate on the consecutive underlined glyph run and connect them into one chunk of underlined characters.
- Vector<GlyphRun>::ConstIterator itGlyphRun = underlineRuns.Begin();
- Vector<GlyphRun>::ConstIterator endItGlyphRun = underlineRuns.End();
- GlyphIndex startGlyphIndex, endGlyphIndex;
-
- //The outer loop to iterate on the separated chunks of underlined glyph runs
- while(itGlyphRun != endItGlyphRun)
+ startGlyphIndex = itGlyphRun->glyphIndex;
+ endGlyphIndex = startGlyphIndex;
+ //The inner loop to make a connected underline for the consecutive characters
+ do
{
- startGlyphIndex = itGlyphRun->glyphIndex;
- endGlyphIndex = startGlyphIndex;
- //The inner loop to make a connected underline for the consecutive characters
- do
- {
- endGlyphIndex += itGlyphRun->numberOfGlyphs;
- itGlyphRun++;
- } while(itGlyphRun != endItGlyphRun && itGlyphRun->glyphIndex == endGlyphIndex);
+ endGlyphIndex += itGlyphRun->numberOfGlyphs;
+ itGlyphRun++;
+ } while(itGlyphRun != endItGlyphRun && itGlyphRun->glyphIndex == endGlyphIndex);
- endGlyphIndex--;
+ endGlyphIndex--;
- // Create the image buffer for underline
- Devel::PixelBuffer underlineImageBuffer = CreateImageBuffer(bufferWidth, bufferHeight, Typesetter::STYLE_UNDERLINE, ignoreHorizontalAlignment, pixelFormat, horizontalOffset, verticalOffset, startGlyphIndex, endGlyphIndex);
- // Combine the two buffers
- topPixelBuffer = CombineImageBuffer(topPixelBuffer, underlineImageBuffer, bufferWidth, bufferHeight);
- }
+ // Create the image buffer for underline
+ Devel::PixelBuffer underlineImageBuffer = CreateImageBuffer(bufferWidth, bufferHeight, Typesetter::STYLE_UNDERLINE, ignoreHorizontalAlignment, pixelFormat, horizontalOffset, verticalOffset, startGlyphIndex, endGlyphIndex);
+ // Combine the two buffers
+ topPixelBuffer = CombineImageBuffer(topPixelBuffer, underlineImageBuffer, bufferWidth, bufferHeight);
}
+ }
- return topPixelBuffer;
+ return topPixelBuffer;
}
Typesetter::Typesetter(const ModelInterface* const model)
+++ /dev/null
-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";
+++ /dev/null
-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";
#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
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(),
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;
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
#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>
#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
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);
#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>
{
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();
* @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
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(),
*/
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.
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
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)
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;
{
namespace Text
{
+struct HyphenInfo
+{
+ Vector<GlyphInfo> glyph;
+ Vector<Vector2> position;
+ Vector<Length> index;
+};
+
class VisualModel;
typedef IntrusivePtr<VisualModel> VisualModelPtr;
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
if(mTextures)
{
mImpl->mRenderer.SetTextures(mTextures);
+ if(DevelTexture::IsNative(mTextures.GetTexture(0)))
+ {
+ UpdateShader();
+ }
mTextures.Reset(); // Visual should not keep a handle to the texture after this point.
}
if(type)
{
auto typeName = type.GetName();
- DevelControl::AppendAccessibilityAttribute(Self(), "t", typeName);
+ DevelControl::AppendAccessibilityAttribute(Self(), "class", typeName);
}
-
- if(Accessibility::IsUp())
- mImpl->AccessibilityRegister();
}
void Control::OnInitialize()
// The clipping renderer is only created if required.
CreateClippingRenderer(*this);
- // Request to be laid out when the control is connected to the Scene.
- // Signal that a Relayout may be needed
- if(Accessibility::IsUp())
- {
- mImpl->AccessibilityRegister();
- }
+ mImpl->AccessibilityRegister();
}
void Control::OnSceneDisconnection()
{
- if(Accessibility::IsUp())
- {
- mImpl->AccessibilityDeregister(true);
- }
+ mImpl->AccessibilityDeregister(true);
mImpl->OnSceneDisconnection();
}
{
const unsigned int TOOLKIT_MAJOR_VERSION = 2;
const unsigned int TOOLKIT_MINOR_VERSION = 0;
-const unsigned int TOOLKIT_MICRO_VERSION = 25;
+const unsigned int TOOLKIT_MICRO_VERSION = 26;
const char* const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
Name: dali2-toolkit
Summary: Dali 3D engine Toolkit
-Version: 2.0.25
+Version: 2.0.26
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-3-Clause and MIT