#include <stdlib.h>
#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/internal/text/text-run-container.h>
#include <dali-toolkit/dali-toolkit.h>
#include <toolkit-text-model.h>
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
{
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<FontDescriptionRun> fontDescriptionRuns;
+ LayoutOptions options;
+ CreateTextModel( data.text,
+ textArea,
+ fontDescriptionRuns,
+ options,
+ layoutSize,
+ logicalModel,
+ visualModel );
+
+ // 2) Clear the paragraphs.
+ Vector<ParagraphRun>& 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<ParagraphRun>::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<FontDescriptionRun> fontDescriptionRuns;
+ LayoutOptions options;
+ CreateTextModel( data.text,
+ textArea,
+ fontDescriptionRuns,
+ options,
+ layoutSize,
+ logicalModel,
+ visualModel );
+
+ // 2) Find the paragraphs.
+ Vector<ParagraphRunIndex> 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<ParagraphRunIndex>::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;
} // 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;
for( unsigned int index = 0u; index < numberOfTests; ++index )
{
+ ToolkitTestApplication application;
if( !SetVisualToLogicalMapTest( data[index] ) )
{
tet_result(TET_FAIL);
utf32.Resize( numberOfCharacters );
- // 2) Set the line break info.
+ // 2) Set the line break info for the whole text.
Vector<LineBreakInfo> 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 )
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;
}
int UtcDaliTextSegnemtationSetLineBreakInfo(void)
{
- ToolkitTestApplication application;
tet_infoline(" UtcDaliTextSegnemtationSetLineBreakInfo");
struct BreakInfoData data[] =
"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"
"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);
int UtcDaliTextSegnemtationSetWordBreakInfo(void)
{
- ToolkitTestApplication application;
tet_infoline(" UtcDaliTextSegnemtationSetWordBreakInfo");
struct BreakInfoData data[] =
for( unsigned int index = 0u; index < numberOfTests; ++index )
{
+ ToolkitTestApplication application;
if( !WordBreakInfoTest( data[index] ) )
{
tet_result(TET_FAIL);
Vector<LineBreakInfo>& lineBreakInfo = logicalModel->mLineBreakInfo;
lineBreakInfo.Resize( numberOfCharacters );
- SetLineBreakInfo( utf32Characters, lineBreakInfo );
+ SetLineBreakInfo( utf32Characters,
+ 0u,
+ numberOfCharacters,
+ lineBreakInfo );
if( 0u == numberOfCharacters )
{
numberOfCharacters,
bidirectionalInfo );
+ // Create the paragraph info.
+ logicalModel->CreateParagraphInfo( 0u,
+ numberOfCharacters );
+
// 6) Set character directions.
Vector<CharacterDirection>& characterDirections = logicalModel->mCharacterDirections;
if( 0u != bidirectionalInfo.Count() )
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<CharacterIndex> 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<ParagraphRun> 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<ParagraphRun>::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<CharacterIndex>::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<ParagraphRun>::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<ParagraphRunIndex>& 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<ParagraphRun>::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();
#include <dali-toolkit/internal/text/color-run.h>
#include <dali-toolkit/internal/text/font-run.h>
#include <dali-toolkit/internal/text/font-description-run.h>
+#include <dali-toolkit/internal/text/paragraph-run.h>
#include <dali-toolkit/internal/text/script-run.h>
namespace Dali
*/
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<ParagraphRunIndex>& paragraphs );
+
protected:
/**
Vector<FontDescriptionRun> mFontDescriptionRuns;
Vector<LineBreakInfo> mLineBreakInfo;
Vector<WordBreakInfo> mWordBreakInfo;
+ Vector<ParagraphRun> mParagraphInfo;
Vector<BidirectionalParagraphInfoRun> mBidirectionalParagraphInfo;
Vector<CharacterDirection> mCharacterDirections; ///< For each character, whether is right to left. ( @e flase is left to right, @e true right to left ).
Vector<BidirectionalLineInfoRun> mBidirectionalLineInfo;
--- /dev/null
+#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 <dali/public-api/math/vector2.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/character-run.h>
+
+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__
{
void SetLineBreakInfo( const Vector<Character>& text,
+ CharacterIndex startIndex,
+ Length numberOfCharacters,
Vector<LineBreakInfo>& 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<LineBreakInfo> 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) )
{
* - 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<Character>& text,
+ CharacterIndex startIndex,
+ Length numberOfCharacters,
Vector<LineBreakInfo>& lineBreakInfo );
/**
lineBreakInfo.Resize( numberOfCharacters, TextAbstraction::LINE_NO_BREAK );
SetLineBreakInfo( utf32Characters,
+ startIndex,
+ requestedNumberOfCharacters,
lineBreakInfo );
+
+ // Create the paragraph info.
+ mLogicalModel->CreateParagraphInfo( startIndex,
+ requestedNumberOfCharacters );
}
Vector<WordBreakInfo>& wordBreakInfo = mLogicalModel->mWordBreakInfo;
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