From: Paul Wisbey
Date: Tue, 12 Apr 2016 10:37:41 +0000 (-0700)
Subject: Merge changes I150e1a74,Ie6d24150,I91081f5a into devel/master
X-Git-Tag: dali_1.1.30~4
X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=e84f2b4052f5a042c6a08d02b87e771bac5ddf44;hp=b98287f646f84cd33e9ffc725f43a562946d13c9
Merge changes I150e1a74,Ie6d24150,I91081f5a into devel/master
* changes:
TextModel - Conversion from characters to glyphs.
TextModel - Create paragraph info for a given range of characters inside a text.
Text - Small fixes.
---
diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-LogicalModel.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-LogicalModel.cpp
index 9ec9930..fa28d61 100644
--- a/automated-tests/src/dali-toolkit-internal/utc-Dali-LogicalModel.cpp
+++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-LogicalModel.cpp
@@ -20,6 +20,7 @@
#include
#include
+#include
#include
#include
@@ -39,6 +40,26 @@ using namespace Text;
namespace
{
+struct CreateParagraphData
+{
+ std::string description; ///< Description of the test.
+ std::string text; ///< Input text.
+ CharacterIndex index; ///< The first character index.
+ Length numberOfCharacters; ///< The number of characters.
+ unsigned int numberOfParagraphs; ///< The expected number of paragraphs.
+ unsigned int* indices; ///< The expected paragraph info indices.
+ unsigned int* numberOfCharactersPerParagraph; ///< The expected number of characters of each paragraph.
+};
+
+struct FindParagraphData
+{
+ std::string description; ///< Description of the test.
+ std::string text; ///< Input text.
+ CharacterIndex index; ///< The first character index.
+ Length numberOfCharacters; ///< The number of characters.
+ unsigned int numberOfParagraphs; ///< The expected number of paragraphs.
+ unsigned int* paragraphs; ///< The expected paragraph info.
+};
struct SetVisualToLogicalMapData
{
@@ -51,6 +72,109 @@ struct SetVisualToLogicalMapData
unsigned int* visualToLogical; ///< The expected visual to logical conversion table.
};
+bool CreateParagraphTest( const CreateParagraphData& data )
+{
+ // 1) Create the model.
+ LogicalModelPtr logicalModel = LogicalModel::New();
+ VisualModelPtr visualModel = VisualModel::New();
+ Size textArea(100.f, 60.f);
+ Size layoutSize;
+
+ Vector fontDescriptionRuns;
+ LayoutOptions options;
+ CreateTextModel( data.text,
+ textArea,
+ fontDescriptionRuns,
+ options,
+ layoutSize,
+ logicalModel,
+ visualModel );
+
+ // 2) Clear the paragraphs.
+ Vector& paragraphs = logicalModel->mParagraphInfo;
+ ClearCharacterRuns( data.index,
+ data.index + data.numberOfCharacters - 1u,
+ paragraphs );
+
+ // 3) Call the LogicalModel::CreateParagraphInfo() method
+ logicalModel->CreateParagraphInfo( data.index,
+ data.numberOfCharacters );
+
+ // 4) Compare the results.
+ if( data.numberOfParagraphs != paragraphs.Count() )
+ {
+ std::cout << " Different number of paragraphs : " << paragraphs.Count() << ", expected : " << data.numberOfParagraphs << std::endl;
+ return false;
+ }
+
+ unsigned int index = 0u;
+ for( Vector::ConstIterator it = paragraphs.Begin(),
+ endIt = paragraphs.End();
+ it != endIt;
+ ++it, ++index )
+ {
+ const ParagraphRun& paragraph( *it );
+
+ if( data.indices[index] != paragraph.characterRun.characterIndex )
+ {
+ std::cout << " Different character index for paragraph : " << index << ", " << paragraph.characterRun.characterIndex << ", expected : " << data.indices[index] << std::endl;
+ return false;
+ }
+ if( data.numberOfCharactersPerParagraph[index] != paragraph.characterRun.numberOfCharacters )
+ {
+ std::cout << " Different number of characters for paragraph : " << index << ", " << paragraph.characterRun.numberOfCharacters << ", expected : " << data.numberOfCharactersPerParagraph[index] << std::endl;
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool FindParagraphTest( const FindParagraphData& data )
+{
+ // 1) Create the model.
+ LogicalModelPtr logicalModel = LogicalModel::New();
+ VisualModelPtr visualModel = VisualModel::New();
+ Size textArea(100.f, 60.f);
+ Size layoutSize;
+
+ Vector fontDescriptionRuns;
+ LayoutOptions options;
+ CreateTextModel( data.text,
+ textArea,
+ fontDescriptionRuns,
+ options,
+ layoutSize,
+ logicalModel,
+ visualModel );
+
+ // 2) Find the paragraphs.
+ Vector paragraphs;
+ logicalModel->FindParagraphs( data.index, data.numberOfCharacters, paragraphs );
+
+ // 3) compare the results.
+ if( data.numberOfParagraphs != paragraphs.Count() )
+ {
+ return false;
+ }
+
+ unsigned int index = 0u;
+ for( Vector::ConstIterator it = paragraphs.Begin(),
+ endIt = paragraphs.End();
+ it != endIt;
+ ++it, ++index )
+ {
+ const ParagraphRunIndex paragraphIndex = *it;
+
+ if( paragraphIndex != data.paragraphs[index] )
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
bool SetVisualToLogicalMapTest( const SetVisualToLogicalMapData& data )
{
std::cout << " testing : " << data.description << std::endl;
@@ -106,10 +230,158 @@ bool SetVisualToLogicalMapTest( const SetVisualToLogicalMapData& data )
} // namespace
//////////////////////////////////////////////////////////
+//
+// UtcDaliCreateParagraph
+// UtcDaliFindParagraph
+// UtcDaliSetVisualToLogicalMap
+//
+//////////////////////////////////////////////////////////
-int UtcDaliSetVisualToLogicalMap(void)
+int UtcDaliCreateParagraph(void)
{
ToolkitTestApplication application;
+ tet_infoline(" UtcDaliCreateParagraph");
+
+ unsigned int paragraphsIndices01[] = { 0u };
+ unsigned int paragraphsNumberOfCharacters01[] = { 0u };
+ unsigned int paragraphsIndices02[] = { 0u, 12u, 17u };
+ unsigned int paragraphsNumberOfCharacters02[] = { 12u, 5u, 1u };
+ unsigned int paragraphsIndices03[] = { 0u, 12u, 17u, 34u };
+ unsigned int paragraphsNumberOfCharacters03[] = { 12u, 5u, 17u ,1u };
+
+ struct CreateParagraphData data[] =
+ {
+ {
+ "Zero characters",
+ "",
+ 0u,
+ 0u,
+ 0u,
+ paragraphsIndices01,
+ paragraphsNumberOfCharacters01,
+ },
+ {
+ "Some paragraphs",
+ "Hello world\ndemo\n\n",
+ 0u,
+ 18u,
+ 3u,
+ paragraphsIndices02,
+ paragraphsNumberOfCharacters02,
+ },
+ {
+ "Some paragraphs. Update the initial paragraphs.",
+ "Hello world\ndemo\nhello world demo\n\n",
+ 0u,
+ 17u,
+ 4u,
+ paragraphsIndices03,
+ paragraphsNumberOfCharacters03,
+ },
+ {
+ "Some paragraphs. Update the mid paragraphs.",
+ "Hello world\ndemo\nhello world demo\n\n",
+ 12u,
+ 5u,
+ 4u,
+ paragraphsIndices03,
+ paragraphsNumberOfCharacters03,
+ },
+ {
+ "Some paragraphs. Update the final paragraphs.",
+ "Hello world\ndemo\nhello world demo\n\n",
+ 17u,
+ 18u,
+ 4u,
+ paragraphsIndices03,
+ paragraphsNumberOfCharacters03,
+ },
+ };
+ const unsigned int numberOfTests = 5u;
+
+ for( unsigned int index = 0u; index < numberOfTests; ++index )
+ {
+ // ToolkitTestApplication application;
+ if( !CreateParagraphTest( data[index] ) )
+ {
+ tet_result(TET_FAIL);
+ }
+ }
+
+ tet_result(TET_PASS);
+ END_TEST;
+}
+
+int UtcDaliFindParagraph(void)
+{
+ tet_infoline(" UtcDaliFindParagraph");
+
+ unsigned int paragraphs01[] = {};
+ unsigned int paragraphs02[] = { 0u, 1u, 2u };
+ unsigned int paragraphs03[] = { 0u };
+ unsigned int paragraphs04[] = { 1u };
+ unsigned int paragraphs05[] = { 0u, 1u, 2u };
+
+ struct FindParagraphData data[] =
+ {
+ {
+ "Zero characters",
+ "",
+ 0u,
+ 100u,
+ 0u,
+ paragraphs01,
+ },
+ {
+ "Some paragraphs",
+ "Hello world\ndemo\n\n",
+ 0u,
+ 18u,
+ 3u,
+ paragraphs02
+ },
+ {
+ "Some paragraphs",
+ "Hello world\ndemo\n\n",
+ 0u,
+ 12u,
+ 1u,
+ paragraphs03
+ },
+ {
+ "Some paragraphs",
+ "Hello world\ndemo\n\n",
+ 12u,
+ 5u,
+ 1u,
+ paragraphs04
+ },
+ {
+ "Some paragraphs",
+ "Hello world\ndemo\n\n",
+ 3u,
+ 15u,
+ 3u,
+ paragraphs05
+ },
+ };
+ const unsigned int numberOfTests = 5u;
+
+ for( unsigned int index = 0u; index < numberOfTests; ++index )
+ {
+ ToolkitTestApplication application;
+ if( !FindParagraphTest( data[index] ) )
+ {
+ tet_result(TET_FAIL);
+ }
+ }
+
+ tet_result(TET_PASS);
+ END_TEST;
+}
+
+int UtcDaliSetVisualToLogicalMap(void)
+{
tet_infoline(" UtcDaliSetVisualToLogicalMap");
unsigned int* visualToLogical01 = NULL;
@@ -210,6 +482,7 @@ int UtcDaliSetVisualToLogicalMap(void)
for( unsigned int index = 0u; index < numberOfTests; ++index )
{
+ ToolkitTestApplication application;
if( !SetVisualToLogicalMapTest( data[index] ) )
{
tet_result(TET_FAIL);
diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Segmentation.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Segmentation.cpp
index 0023240..5366164 100644
--- a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Segmentation.cpp
+++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Segmentation.cpp
@@ -62,13 +62,31 @@ bool LineBreakInfoTest( const BreakInfoData& data )
utf32.Resize( numberOfCharacters );
- // 2) Set the line break info.
+ // 2) Set the line break info for the whole text.
Vector lineBreakInfo;
lineBreakInfo.Resize( numberOfCharacters );
- SetLineBreakInfo( utf32, lineBreakInfo );
+ SetLineBreakInfo( utf32,
+ 0u,
+ numberOfCharacters,
+ lineBreakInfo );
+
+ // 3) Update the word text info if it's requested for part of the text.
+ if( ( 0u != data.index ) &&
+ ( numberOfCharacters != data.numberOfCharacters ) )
+ {
+ // Clear part of the line break info.
+ lineBreakInfo.Erase( lineBreakInfo.Begin() + data.index,
+ lineBreakInfo.Begin() + data.index + data.numberOfCharacters );
- // 3) compare the results
+ // Update the word line info.
+ SetLineBreakInfo( utf32,
+ data.index,
+ data.numberOfCharacters,
+ lineBreakInfo );
+ }
+
+ // 4) compare the results
std::ostringstream breakInfo;
for( unsigned int index = 0u; index < numberOfCharacters; ++index )
@@ -78,8 +96,11 @@ bool LineBreakInfoTest( const BreakInfoData& data )
if( data.breakInfo != breakInfo.str() )
{
- std::cout << " expected : [" << data.breakInfo << "]" << std::endl;
- std::cout << " got : [" << breakInfo.str() << "]" << std::endl;
+ std::cout << " text : [" << data.text << "]" << std::endl;
+ std::cout << " index : " << data.index << std::endl;
+ std::cout << " numberOfCharacters : " << data.numberOfCharacters << std::endl;
+ std::cout << " expected : [" << data.breakInfo << "]" << std::endl;
+ std::cout << " got : [" << breakInfo.str() << "]" << std::endl;
return false;
}
@@ -149,7 +170,6 @@ bool WordBreakInfoTest( const BreakInfoData& data )
int UtcDaliTextSegnemtationSetLineBreakInfo(void)
{
- ToolkitTestApplication application;
tet_infoline(" UtcDaliTextSegnemtationSetLineBreakInfo");
struct BreakInfoData data[] =
@@ -177,6 +197,51 @@ int UtcDaliTextSegnemtationSetLineBreakInfo(void)
"222222122222221221222212212221222222122222222220",
},
{
+ "Latin script. Update initial paragraphs.",
+ "Lorem ipsum dolor sit amet, aeque definiebas ea mei, posse iracundia ne cum.\n"
+ "Usu ne nisl maiorum iudicabit, veniam epicurei oporteat eos an.\n"
+ "Ne nec nulla regione albucius, mea doctus delenit ad!\n"
+ "Et everti blandit adversarium mei, eam porro neglegentur suscipiantur an.\n"
+ "Quidam corpora at duo. An eos possim scripserit?",
+ 0u,
+ 141u,
+ "22222122222122222122212222212222212222222222122122221222221222222222122122220"
+ "2221221222212222222122222222221222222122222222122222222122212220"
+ "221222122222122222221222222222122212222221222222212220"
+ "22122222212222222122222222222122221222122222122222222222122222222222212220"
+ "222222122222221221222212212221222222122222222220",
+ },
+ {
+ "Latin script. Update mid paragraphs.",
+ "Lorem ipsum dolor sit amet, aeque definiebas ea mei, posse iracundia ne cum.\n"
+ "Usu ne nisl maiorum iudicabit, veniam epicurei oporteat eos an.\n"
+ "Ne nec nulla regione albucius, mea doctus delenit ad!\n"
+ "Et everti blandit adversarium mei, eam porro neglegentur suscipiantur an.\n"
+ "Quidam corpora at duo. An eos possim scripserit?",
+ 141u,
+ 128u,
+ "22222122222122222122212222212222212222222222122122221222221222222222122122220"
+ "2221221222212222222122222222221222222122222222122222222122212220"
+ "221222122222122222221222222222122212222221222222212220"
+ "22122222212222222122222222222122221222122222122222222222122222222222212220"
+ "222222122222221221222212212221222222122222222220",
+ },
+ {
+ "Latin script. Update final paragraphs.",
+ "Lorem ipsum dolor sit amet, aeque definiebas ea mei, posse iracundia ne cum.\n"
+ "Usu ne nisl maiorum iudicabit, veniam epicurei oporteat eos an.\n"
+ "Ne nec nulla regione albucius, mea doctus delenit ad!\n"
+ "Et everti blandit adversarium mei, eam porro neglegentur suscipiantur an.\n"
+ "Quidam corpora at duo. An eos possim scripserit?",
+ 195u,
+ 122u,
+ "22222122222122222122212222212222212222222222122122221222221222222222122122220"
+ "2221221222212222222122222222221222222122222222122222222122212220"
+ "221222122222122222221222222222122212222221222222212220"
+ "22122222212222222122222222222122221222122222122222222222122222222222212220"
+ "222222122222221221222212212221222222122222222220",
+ },
+ {
"Japanese script",
"éå½å´ã¯åæé®®å½å±ãéãã¦ç±³ãã«ã§è³éãæ¯æãã\n"
"å½é社ä¼ããæ§ã
ãªçµæ¸å¶è£ãåããåæé®®ã«ã¨ã£ã¦ã¯åºç¨¼ãå´åãªã©ã¨ä¸¦ãã§éè¦ãªå¤è²¨ç¨¼ãã®æ段ã¨ãªã£ã¦ããã\n"
@@ -199,10 +264,11 @@ int UtcDaliTextSegnemtationSetLineBreakInfo(void)
"21111112112111111111111211121111111111120",
}
};
- const unsigned int numberOfTests = 4u;
+ const unsigned int numberOfTests = 7u;
for( unsigned int index = 0u; index < numberOfTests; ++index )
{
+ ToolkitTestApplication application;
if( !LineBreakInfoTest( data[index] ) )
{
tet_result(TET_FAIL);
@@ -215,7 +281,6 @@ int UtcDaliTextSegnemtationSetLineBreakInfo(void)
int UtcDaliTextSegnemtationSetWordBreakInfo(void)
{
- ToolkitTestApplication application;
tet_infoline(" UtcDaliTextSegnemtationSetWordBreakInfo");
struct BreakInfoData data[] =
@@ -380,6 +445,7 @@ int UtcDaliTextSegnemtationSetWordBreakInfo(void)
for( unsigned int index = 0u; index < numberOfTests; ++index )
{
+ ToolkitTestApplication application;
if( !WordBreakInfoTest( data[index] ) )
{
tet_result(TET_FAIL);
diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-VisualModel.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-VisualModel.cpp
index fdde254..fe6d4cb 100644
--- a/automated-tests/src/dali-toolkit-internal/utc-Dali-VisualModel.cpp
+++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-VisualModel.cpp
@@ -84,10 +84,12 @@ bool SetGlyphsPerCharacterTest( const SetGlyphsPerCharacterData& data )
Vector& charactersToGlyph = visualModel->mCharactersToGlyph;
Vector& glyphsPerCharacter = visualModel->mGlyphsPerCharacter;
+ GlyphIndex startGlyphIndex = 0u;
if( 0u != charactersToGlyph.Count() )
{
// The number of glyphs to be removed.
const Length numberOfGlyphs = charactersToGlyph[data.startIndex + data.numberOfCharacters - 1u] + glyphsPerCharacter[data.startIndex + data.numberOfCharacters - 1u] - charactersToGlyph[data.startIndex];
+ startGlyphIndex = charactersToGlyph[data.startIndex];
charactersToGlyph.Erase( charactersToGlyph.Begin() + data.startIndex,
charactersToGlyph.Begin() + data.startIndex + data.numberOfCharacters );
@@ -106,6 +108,7 @@ bool SetGlyphsPerCharacterTest( const SetGlyphsPerCharacterData& data )
// 3) Call the CreateGlyphsPerCharacterTable() function
visualModel->CreateGlyphsPerCharacterTable( data.startIndex,
+ startGlyphIndex,
data.numberOfCharacters );
// 4) Compare the results.
@@ -160,10 +163,12 @@ bool SetCharacterToGlyphTest( const SetCharacterToGlyphData& data )
Vector& charactersToGlyph = visualModel->mCharactersToGlyph;
Vector& glyphsPerCharacter = visualModel->mGlyphsPerCharacter;
+ GlyphIndex startGlyphIndex = 0u;
if( 0u != charactersToGlyph.Count() )
{
// The number of glyphs to be removed.
const Length numberOfGlyphs = charactersToGlyph[data.startIndex + data.numberOfCharacters - 1u] + glyphsPerCharacter[data.startIndex + data.numberOfCharacters - 1u] - charactersToGlyph[data.startIndex];
+ startGlyphIndex = charactersToGlyph[data.startIndex];
charactersToGlyph.Erase( charactersToGlyph.Begin() + data.startIndex,
charactersToGlyph.Begin() + data.startIndex + data.numberOfCharacters );
@@ -180,6 +185,7 @@ bool SetCharacterToGlyphTest( const SetCharacterToGlyphData& data )
// 3) Call the CreateCharacterToGlyphTable() function
visualModel->CreateCharacterToGlyphTable( data.startIndex,
+ startGlyphIndex,
data.numberOfCharacters );
// 4) Compare the results.
diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-text-model.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-text-model.cpp
index 5bde6be..aff7eb7 100644
--- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-text-model.cpp
+++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-text-model.cpp
@@ -116,7 +116,10 @@ void CreateTextModel( const std::string& text,
Vector& lineBreakInfo = logicalModel->mLineBreakInfo;
lineBreakInfo.Resize( numberOfCharacters );
- SetLineBreakInfo( utf32Characters, lineBreakInfo );
+ SetLineBreakInfo( utf32Characters,
+ 0u,
+ numberOfCharacters,
+ lineBreakInfo );
if( 0u == numberOfCharacters )
{
@@ -184,6 +187,10 @@ void CreateTextModel( const std::string& text,
numberOfCharacters,
bidirectionalInfo );
+ // Create the paragraph info.
+ logicalModel->CreateParagraphInfo( 0u,
+ numberOfCharacters );
+
// 6) Set character directions.
Vector& characterDirections = logicalModel->mCharacterDirections;
if( 0u != bidirectionalInfo.Count() )
@@ -232,8 +239,8 @@ void CreateTextModel( const std::string& text,
newParagraphGlyphs );
// Create the 'number of glyphs' per character and the glyph to character conversion tables.
- visualModel->CreateGlyphsPerCharacterTable( 0u, numberOfCharacters );
- visualModel->CreateCharacterToGlyphTable( 0u, numberOfCharacters );
+ visualModel->CreateGlyphsPerCharacterTable( 0u, 0u, numberOfCharacters );
+ visualModel->CreateCharacterToGlyphTable( 0u, 0u, numberOfCharacters );
const Length numberOfGlyphs = glyphs.Count();
diff --git a/dali-toolkit/internal/text/logical-model-impl.cpp b/dali-toolkit/internal/text/logical-model-impl.cpp
index 8af3e91..239a2f8 100644
--- a/dali-toolkit/internal/text/logical-model-impl.cpp
+++ b/dali-toolkit/internal/text/logical-model-impl.cpp
@@ -420,6 +420,131 @@ void LogicalModel::ClearFontDescriptionRuns()
FreeFontFamilyNames( mFontDescriptionRuns );
}
+void LogicalModel::CreateParagraphInfo( CharacterIndex startIndex,
+ Length numberOfCharacters )
+{
+ const Length totalNumberOfCharacters = mLineBreakInfo.Count();
+
+ // Count the number of LINE_MUST_BREAK to reserve some space for the vector of paragraph's info.
+ Vector paragraphs;
+ paragraphs.Reserve( numberOfCharacters );
+ const TextAbstraction::LineBreakInfo* lineBreakInfoBuffer = mLineBreakInfo.Begin();
+ const CharacterIndex lastCharacterIndexPlusOne = startIndex + numberOfCharacters;
+ for( Length index = startIndex; index < lastCharacterIndexPlusOne; ++index )
+ {
+ if( TextAbstraction::LINE_MUST_BREAK == *( lineBreakInfoBuffer + index ) )
+ {
+ paragraphs.PushBack( index );
+ }
+ }
+
+ // Whether the current paragraphs are updated or set from scratch.
+ const bool updateCurrentParagraphs = numberOfCharacters < totalNumberOfCharacters;
+
+ // Reserve space for current paragraphs plus new ones.
+ const Length numberOfNewParagraphs = paragraphs.Count();
+ const Length totalNumberOfParagraphs = mParagraphInfo.Count() + numberOfNewParagraphs;
+ mParagraphInfo.Resize( totalNumberOfParagraphs );
+
+ ParagraphRun* paragraphInfoBuffer = NULL;
+ Vector newParagraphs;
+
+ if( updateCurrentParagraphs )
+ {
+ newParagraphs.Resize( numberOfNewParagraphs );
+ paragraphInfoBuffer = newParagraphs.Begin();
+ }
+ else
+ {
+ paragraphInfoBuffer = mParagraphInfo.Begin();
+ }
+
+ // Find where to insert the new paragraphs.
+ ParagraphRunIndex paragraphIndex = 0u;
+ CharacterIndex firstIndex = startIndex;
+
+ if( updateCurrentParagraphs )
+ {
+ for( Vector::ConstIterator it = mParagraphInfo.Begin(),
+ endIt = mParagraphInfo.Begin() + totalNumberOfParagraphs - numberOfNewParagraphs;
+ it != endIt;
+ ++it )
+ {
+ const ParagraphRun& paragraph( *it );
+
+ if( startIndex < paragraph.characterRun.characterIndex + paragraph.characterRun.numberOfCharacters )
+ {
+ firstIndex = paragraph.characterRun.characterIndex;
+ break;
+ }
+
+ ++paragraphIndex;
+ }
+ }
+
+ // Create the paragraph info.
+ ParagraphRunIndex newParagraphIndex = 0u;
+ for( Vector::ConstIterator it = paragraphs.Begin(),
+ endIt = paragraphs.End();
+ it != endIt;
+ ++it, ++newParagraphIndex )
+ {
+ const CharacterIndex index = *it;
+
+ ParagraphRun& paragraph = *( paragraphInfoBuffer + newParagraphIndex );
+ paragraph.characterRun.characterIndex = firstIndex;
+ paragraph.characterRun.numberOfCharacters = 1u + index - firstIndex;
+
+ firstIndex += paragraph.characterRun.numberOfCharacters;
+ }
+
+
+ // Insert the new paragraphs.
+ if( updateCurrentParagraphs )
+ {
+ mParagraphInfo.Insert( mParagraphInfo.Begin() + paragraphIndex,
+ newParagraphs.Begin(),
+ newParagraphs.End() );
+
+ mParagraphInfo.Resize( totalNumberOfParagraphs );
+
+ // Update the next paragraph indices.
+ for( Vector::Iterator it = mParagraphInfo.Begin() + paragraphIndex + newParagraphs.Count(),
+ endIt = mParagraphInfo.End();
+ it != endIt;
+ ++it )
+ {
+ ParagraphRun& paragraph( *it );
+
+ paragraph.characterRun.characterIndex += numberOfCharacters;
+ }
+ }
+}
+
+void LogicalModel::FindParagraphs( CharacterIndex index,
+ Length numberOfCharacters,
+ Vector& paragraphs )
+{
+ // Reserve som space for the paragraph indices.
+ paragraphs.Reserve( mParagraphInfo.Count() );
+
+ // Traverse the paragraphs to find which ones contain the given characters.
+ ParagraphRunIndex paragraphIndex = 0u;
+ for( Vector::ConstIterator it = mParagraphInfo.Begin(),
+ endIt = mParagraphInfo.End();
+ it != endIt;
+ ++it, ++paragraphIndex )
+ {
+ const ParagraphRun& paragraph( *it );
+
+ if( ( paragraph.characterRun.characterIndex + paragraph.characterRun.numberOfCharacters > index ) &&
+ ( paragraph.characterRun.characterIndex < index + numberOfCharacters ) )
+ {
+ paragraphs.PushBack( paragraphIndex );
+ }
+ }
+}
+
LogicalModel::~LogicalModel()
{
ClearFontDescriptionRuns();
diff --git a/dali-toolkit/internal/text/logical-model-impl.h b/dali-toolkit/internal/text/logical-model-impl.h
index 7085d79..e41f0fa 100644
--- a/dali-toolkit/internal/text/logical-model-impl.h
+++ b/dali-toolkit/internal/text/logical-model-impl.h
@@ -29,6 +29,7 @@
#include
#include
#include
+#include
#include
namespace Dali
@@ -136,6 +137,30 @@ public:
*/
void ClearFontDescriptionRuns();
+ // Paragraphs
+
+ /**
+ * @brief Creates the paragraph info.
+ *
+ * @pre The line break info must be set.
+ *
+ * @param[in] startIndex The character from where the paragraph info is set.
+ * @param[in] numberOfCharacters The number of characters.
+ */
+ void CreateParagraphInfo( CharacterIndex startIndex,
+ Length numberOfCharacters );
+
+ /**
+ * @brief Find the paragraphs which contains the given characters.
+ *
+ * @param[in] index The first character's index of the run.
+ * @param[in] numberOfCharacters The number of characters of the run.
+ * @param[out] paragraphs Indices to the paragraphs which contain the characters.
+ */
+ void FindParagraphs( CharacterIndex index,
+ Length numberOfCharacters,
+ Vector& paragraphs );
+
protected:
/**
@@ -165,6 +190,7 @@ public:
Vector mFontDescriptionRuns;
Vector mLineBreakInfo;
Vector mWordBreakInfo;
+ Vector mParagraphInfo;
Vector mBidirectionalParagraphInfo;
Vector mCharacterDirections; ///< For each character, whether is right to left. ( @e flase is left to right, @e true right to left ).
Vector mBidirectionalLineInfo;
diff --git a/dali-toolkit/internal/text/paragraph-run.h b/dali-toolkit/internal/text/paragraph-run.h
new file mode 100644
index 0000000..7a90363
--- /dev/null
+++ b/dali-toolkit/internal/text/paragraph-run.h
@@ -0,0 +1,54 @@
+#ifndef __DALI_TOOLKIT_TEXT_PARAGRAPH_RUN_H__
+#define __DALI_TOOLKIT_TEXT_PARAGRAPH_RUN_H__
+
+/*
+ * Copyright (c) 2016 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
+
+// INTERNAL INCLUDES
+#include
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+/**
+ * @brief ParagraphRun
+ *
+ * In terms of the bidirectional algorithm, a 'paragraph' is understood as a run of characters between Paragraph Separators or appropriate Newline Functions.
+ * A 'paragraph' may also be determined by higher-level protocols like a mark-up tag.
+ */
+struct ParagraphRun
+{
+ CharacterRun characterRun; ///< The initial character index within the whole text and the number of characters of the run.
+ Size layoutSize; ///< The size of the paragraph when is laid-out.
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_PARAGRAPH_RUN_H__
diff --git a/dali-toolkit/internal/text/segmentation.cpp b/dali-toolkit/internal/text/segmentation.cpp
index 5e590b5..61afef1 100644
--- a/dali-toolkit/internal/text/segmentation.cpp
+++ b/dali-toolkit/internal/text/segmentation.cpp
@@ -50,21 +50,51 @@ namespace Text
{
void SetLineBreakInfo( const Vector& text,
+ CharacterIndex startIndex,
+ Length numberOfCharacters,
Vector& lineBreakInfo )
{
- const Length numberOfCharacters = text.Count();
+ const Length totalNumberOfCharacters = text.Count();
- if( 0u == numberOfCharacters )
+ if( 0u == totalNumberOfCharacters )
{
// Nothing to do if there are no characters.
return;
}
// Retrieve the line break info.
- lineBreakInfo.Resize( numberOfCharacters );
- TextAbstraction::Segmentation::Get().GetLineBreakPositions( text.Begin(),
+ lineBreakInfo.Resize( totalNumberOfCharacters );
+
+ // Whether the current buffer is being updated or is set from scratch.
+ const bool updateCurrentBuffer = numberOfCharacters < totalNumberOfCharacters;
+
+ LineBreakInfo* lineBreakInfoBuffer = NULL;
+ Vector newLineBreakInfo;
+
+ if( updateCurrentBuffer )
+ {
+ newLineBreakInfo.Resize( numberOfCharacters );
+ lineBreakInfoBuffer = newLineBreakInfo.Begin();
+ }
+ else
+ {
+ lineBreakInfoBuffer = lineBreakInfo.Begin();
+ }
+
+ // Retrieve the line break info.
+ TextAbstraction::Segmentation::Get().GetLineBreakPositions( text.Begin() + startIndex,
numberOfCharacters,
- lineBreakInfo.Begin() );
+ lineBreakInfoBuffer );
+
+ // If the line break info is updated, it needs to be inserted in the model.
+ if( updateCurrentBuffer )
+ {
+ lineBreakInfo.Insert( lineBreakInfo.Begin() + startIndex,
+ newLineBreakInfo.Begin(),
+ newLineBreakInfo.End() );
+ lineBreakInfo.Resize( totalNumberOfCharacters );
+ }
+
#ifdef DEBUG_ENABLED
if( gLogFilter->IsEnabledFor(Debug::Verbose) )
{
diff --git a/dali-toolkit/internal/text/segmentation.h b/dali-toolkit/internal/text/segmentation.h
index 61ddcc7..e23065a 100644
--- a/dali-toolkit/internal/text/segmentation.h
+++ b/dali-toolkit/internal/text/segmentation.h
@@ -45,9 +45,13 @@ class LogicalModel;
* - 2 is a LINE_NO_BREAK. Text can't be broken into a new line.
*
* @param[in] text Vector of UTF-32 characters.
+ * @param[in] startIndex The character from where the break info is set.
+ * @param[in] numberOfCharacters The number of characters.
* @param[out] lineBreakInfo The line break info
*/
void SetLineBreakInfo( const Vector& text,
+ CharacterIndex startIndex,
+ Length numberOfCharacters,
Vector& lineBreakInfo );
/**
diff --git a/dali-toolkit/internal/text/shaper.cpp b/dali-toolkit/internal/text/shaper.cpp
index 5313d0c..cd0b1d7 100644
--- a/dali-toolkit/internal/text/shaper.cpp
+++ b/dali-toolkit/internal/text/shaper.cpp
@@ -175,7 +175,7 @@ void ShapeText( const Vector& text,
shaping.GetGlyphs( tmpGlyphs.Begin(),
tmpGlyphToCharacterMap.Begin() );
- // Update the indices.
+ // Update the new indices of the glyph to character map.
if( 0u != totalNumberOfGlyphs )
{
for( Vector::Iterator it = tmpGlyphToCharacterMap.Begin(),
diff --git a/dali-toolkit/internal/text/text-controller-impl.cpp b/dali-toolkit/internal/text/text-controller-impl.cpp
index d681730..5571f94 100644
--- a/dali-toolkit/internal/text/text-controller-impl.cpp
+++ b/dali-toolkit/internal/text/text-controller-impl.cpp
@@ -336,7 +336,13 @@ void Controller::Impl::UpdateModel( OperationsMask operationsRequired )
lineBreakInfo.Resize( numberOfCharacters, TextAbstraction::LINE_NO_BREAK );
SetLineBreakInfo( utf32Characters,
+ startIndex,
+ requestedNumberOfCharacters,
lineBreakInfo );
+
+ // Create the paragraph info.
+ mLogicalModel->CreateParagraphInfo( startIndex,
+ requestedNumberOfCharacters );
}
Vector& wordBreakInfo = mLogicalModel->mWordBreakInfo;
@@ -471,8 +477,8 @@ void Controller::Impl::UpdateModel( OperationsMask operationsRequired )
newParagraphGlyphs );
// Create the 'number of glyphs' per character and the glyph to character conversion tables.
- mVisualModel->CreateGlyphsPerCharacterTable( startIndex, numberOfCharacters );
- mVisualModel->CreateCharacterToGlyphTable( startIndex, numberOfCharacters );
+ mVisualModel->CreateGlyphsPerCharacterTable( startIndex, startGlyphIndex, numberOfCharacters );
+ mVisualModel->CreateCharacterToGlyphTable( startIndex, startGlyphIndex, numberOfCharacters );
}
const Length numberOfGlyphs = glyphs.Count();
diff --git a/dali-toolkit/internal/text/text-controller.cpp b/dali-toolkit/internal/text/text-controller.cpp
index 153a36c..ab41790 100644
--- a/dali-toolkit/internal/text/text-controller.cpp
+++ b/dali-toolkit/internal/text/text-controller.cpp
@@ -466,7 +466,7 @@ float Controller::GetDefaultPointSize() const
return 0.0f;
}
-void Controller::UpdateAfterFontChange( std::string& newDefaultFont )
+void Controller::UpdateAfterFontChange( const std::string& newDefaultFont )
{
DALI_LOG_INFO( gLogFilter, Debug::Concise, "Controller::UpdateAfterFontChange");
@@ -499,7 +499,7 @@ const Vector4& Controller::GetTextColor() const
return mImpl->mTextColor;
}
-bool Controller::RemoveText( int cursorOffset, int numberOfChars )
+bool Controller::RemoveText( int cursorOffset, int numberOfCharacters )
{
bool removed = false;
@@ -508,8 +508,8 @@ bool Controller::RemoveText( int cursorOffset, int numberOfChars )
return removed;
}
- DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::RemoveText %p mText.Count() %d cursor %d cursorOffset %d numberOfChars %d\n",
- this, mImpl->mLogicalModel->mText.Count(), mImpl->mEventData->mPrimaryCursorPosition, cursorOffset, numberOfChars );
+ DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::RemoveText %p mText.Count() %d cursor %d cursorOffset %d numberOfCharacters %d\n",
+ this, mImpl->mLogicalModel->mText.Count(), mImpl->mEventData->mPrimaryCursorPosition, cursorOffset, numberOfCharacters );
if( !mImpl->IsShowingPlaceholderText() )
{
@@ -525,12 +525,12 @@ bool Controller::RemoveText( int cursorOffset, int numberOfChars )
cursorIndex = oldCursorIndex + cursorOffset;
}
- if( ( cursorIndex + numberOfChars ) > currentText.Count() )
+ if( ( cursorIndex + numberOfCharacters ) > currentText.Count() )
{
- numberOfChars = currentText.Count() - cursorIndex;
+ numberOfCharacters = currentText.Count() - cursorIndex;
}
- if( ( cursorIndex + numberOfChars ) <= currentText.Count() )
+ if( ( cursorIndex + numberOfCharacters ) <= currentText.Count() )
{
// Update the input style and remove the text's style before removing the text.
@@ -541,18 +541,18 @@ bool Controller::RemoveText( int cursorOffset, int numberOfChars )
mImpl->mLogicalModel->RetrieveStyle( cursorIndex, mImpl->mEventData->mInputStyle );
// Remove the text's style before removing the text.
- mImpl->mLogicalModel->UpdateTextStyleRuns( cursorIndex, -numberOfChars );
+ mImpl->mLogicalModel->UpdateTextStyleRuns( cursorIndex, -numberOfCharacters );
// Remove the characters.
Vector::Iterator first = currentText.Begin() + cursorIndex;
- Vector::Iterator last = first + numberOfChars;
+ Vector::Iterator last = first + numberOfCharacters;
currentText.Erase( first, last );
// Cursor position retreat
oldCursorIndex = cursorIndex;
- DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::RemoveText %p removed %d\n", this, numberOfChars );
+ DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::RemoveText %p removed %d\n", this, numberOfCharacters );
removed = true;
}
}
@@ -1776,14 +1776,14 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ
// Remove the previous IMF pre-edit (predicitive text)
if( mImpl->mEventData->mPreEditFlag &&
- ( 0 != mImpl->mEventData->mPreEditLength ) )
+ ( 0u != mImpl->mEventData->mPreEditLength ) )
{
- CharacterIndex offset = mImpl->mEventData->mPrimaryCursorPosition - mImpl->mEventData->mPreEditStartPosition;
+ const CharacterIndex offset = mImpl->mEventData->mPrimaryCursorPosition - mImpl->mEventData->mPreEditStartPosition;
- removedPrevious = RemoveText( -static_cast(offset), mImpl->mEventData->mPreEditLength );
+ removedPrevious = RemoveText( -static_cast( offset ), mImpl->mEventData->mPreEditLength );
mImpl->mEventData->mPrimaryCursorPosition = mImpl->mEventData->mPreEditStartPosition;
- mImpl->mEventData->mPreEditLength = 0;
+ mImpl->mEventData->mPreEditLength = 0u;
}
else
{
@@ -1842,7 +1842,7 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ
const Length numberOfCharactersInModel = mImpl->mLogicalModel->mText.Count();
- // Restrict new text to fit within Maximum characters setting
+ // Restrict new text to fit within Maximum characters setting.
Length maxSizeOfNewText = std::min( ( mImpl->mMaximumNumberOfCharacters - numberOfCharactersInModel ), characterCount );
maxLengthReached = ( characterCount > maxSizeOfNewText );
@@ -2514,7 +2514,7 @@ void Controller::ShowPlaceholderText()
// Transform a text array encoded in utf8 into an array encoded in utf32.
// It returns the actual number of characters.
- Length characterCount = Utf8ToUtf32( utf8, size, utf32Characters.Begin() );
+ const Length characterCount = Utf8ToUtf32( utf8, size, utf32Characters.Begin() );
utf32Characters.Resize( characterCount );
// Reset the cursor position
diff --git a/dali-toolkit/internal/text/text-controller.h b/dali-toolkit/internal/text/text-controller.h
index d239d13..7e22134 100644
--- a/dali-toolkit/internal/text/text-controller.h
+++ b/dali-toolkit/internal/text/text-controller.h
@@ -151,10 +151,10 @@ public:
* @brief Remove a given number of characters
*
* @param[in] cursorOffset Start position from the current cursor position to start deleting characters.
- * @param[in] numberOfChars The number of characters to delete from the cursorOffset.
+ * @param[in] numberOfCharacters The number of characters to delete from the cursorOffset.
* @return True if the remove was successful.
*/
- bool RemoveText( int cursorOffset, int numberOfChars );
+ bool RemoveText( int cursorOffset, int numberOfCharacters );
/**
* @brief Retrieve the current cursor position.
@@ -283,7 +283,7 @@ public:
* @ brief Update the text after a font change
* @param[in] newDefaultFont The new font to change to
*/
- void UpdateAfterFontChange( std::string& newDefaultFont );
+ void UpdateAfterFontChange( const std::string& newDefaultFont );
/**
* @brief Set the text color
diff --git a/dali-toolkit/internal/text/text-definitions.h b/dali-toolkit/internal/text/text-definitions.h
index 4879090..0e9fb3f 100644
--- a/dali-toolkit/internal/text/text-definitions.h
+++ b/dali-toolkit/internal/text/text-definitions.h
@@ -59,6 +59,7 @@ typedef uint32_t UnderlineRunIndex; ///< An inde
typedef uint32_t BidirectionalRunIndex; ///< An index into an array of bidirectional info.
typedef uint32_t BidirectionalLineRunIndex; ///< An index into an array of bidirectional line info.
typedef uint32_t LineIndex; ///< An index into an array of lines.
+typedef uint32_t ParagraphRunIndex; ///< An index into an array of paragraphs.
} // namespace Text
diff --git a/dali-toolkit/internal/text/text-run-container.h b/dali-toolkit/internal/text/text-run-container.h
index 37d7b00..ecac39d 100644
--- a/dali-toolkit/internal/text/text-run-container.h
+++ b/dali-toolkit/internal/text/text-run-container.h
@@ -1,8 +1,8 @@
-#ifndef __DALI_TOOLKIT_TEXT_STYLE_RUN_CONTAINER_H__
-#define __DALI_TOOLKIT_TEXT_STYLE_RUN_CONTAINER_H__
+#ifndef __DALI_TOOLKIT_TEXT_RUN_CONTAINER_H__
+#define __DALI_TOOLKIT_TEXT_RUN_CONTAINER_H__
/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
@@ -300,6 +300,7 @@ void ClearGlyphRuns( GlyphIndex startIndex,
( startIndex >= run->glyphRun.glyphIndex + run->glyphRun.numberOfGlyphs ) )
{
// Run found. Nothing else to do.
+ break;
}
++run;
@@ -352,4 +353,4 @@ void ClearGlyphRuns( GlyphIndex startIndex,
} // namespace Dali
-#endif // __DALI_TOOLKIT_TEXT_STYLE_RUN_CONTAINER_H__
+#endif // __DALI_TOOLKIT_TEXT_RUN_CONTAINER_H__
diff --git a/dali-toolkit/internal/text/visual-model-impl.cpp b/dali-toolkit/internal/text/visual-model-impl.cpp
index 138ce54..c1faee7 100644
--- a/dali-toolkit/internal/text/visual-model-impl.cpp
+++ b/dali-toolkit/internal/text/visual-model-impl.cpp
@@ -36,6 +36,7 @@ VisualModelPtr VisualModel::New()
}
void VisualModel::CreateCharacterToGlyphTable( CharacterIndex startIndex,
+ GlyphIndex startGlyphIndex,
Length numberOfCharacters )
{
if( 0u == numberOfCharacters )
@@ -72,7 +73,6 @@ void VisualModel::CreateCharacterToGlyphTable( CharacterIndex startIndex,
// 2) Traverse the glyphs and set the glyph indices per character.
// Index to the glyph.
- const GlyphIndex startGlyphIndex = updateCurrentBuffer ? *( mCharactersToGlyph.Begin() + startIndex ) : 0u;
GlyphIndex glyphIndex = startGlyphIndex;
CharacterIndex characterIndex = startIndex;
const CharacterIndex lastCharacterIndexPlusOne = startIndex + numberOfCharacters;
@@ -115,6 +115,7 @@ void VisualModel::CreateCharacterToGlyphTable( CharacterIndex startIndex,
}
void VisualModel::CreateGlyphsPerCharacterTable( CharacterIndex startIndex,
+ GlyphIndex startGlyphIndex,
Length numberOfCharacters )
{
if( 0u == numberOfCharacters )
@@ -146,14 +147,12 @@ void VisualModel::CreateGlyphsPerCharacterTable( CharacterIndex startIndex,
// 2) Traverse the glyphs and set the number of glyphs per character.
- // The glyph index.
- const GlyphIndex glyphIndex = updateCurrentBuffer ? *( mCharactersToGlyph.Begin() + startIndex ) : 0u;
Length traversedCharacters = 0;
// The number of 'characters per glyph' equal to zero.
Length zeroCharactersPerGlyph = 0u;
- for( Vector::ConstIterator it = mCharactersPerGlyph.Begin() + glyphIndex,
+ for( Vector::ConstIterator it = mCharactersPerGlyph.Begin() + startGlyphIndex,
endIt = mCharactersPerGlyph.End();
( it != endIt ) && ( traversedCharacters < numberOfCharacters );
++it )
diff --git a/dali-toolkit/internal/text/visual-model-impl.h b/dali-toolkit/internal/text/visual-model-impl.h
index a0339a4..5aa90af 100644
--- a/dali-toolkit/internal/text/visual-model-impl.h
+++ b/dali-toolkit/internal/text/visual-model-impl.h
@@ -67,18 +67,22 @@ public:
* @pre The glyphs per character table needs to be created first.
*
* @param[in] startIndex The character from where the conversion table is created.
+ * @param[in] startGlyphIndex The glyph from where the conversion table is created.
* @param[in] numberOfCharacters The number of characters.
*/
void CreateCharacterToGlyphTable( CharacterIndex startIndex,
+ GlyphIndex startGlyphIndex,
Length numberOfCharacters );
/**
* @brief Creates an array containing the number of glyphs per character.
*
* @param[in] startIndex The character from where the table is created.
+ * @param[in] startGlyphIndex The glyph from where the conversion table is created.
* @param[in] numberOfCharacters The number of characters.
*/
void CreateGlyphsPerCharacterTable( CharacterIndex startIndex,
+ GlyphIndex startGlyphIndex,
Length numberOfCharacters );
/**