2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali-toolkit/internal/controls/text-view/split-by-char-policies.h>
22 #include <dali/integration-api/debug.h>
23 #include <dali-toolkit/internal/controls/text-view/relayout-utilities.h>
24 #include <dali-toolkit/internal/controls/text-view/text-view-processor.h>
41 Vector3 NoShrinkWhenExceedPosition( const TextViewRelayout::RelayoutParameters& relayoutParameters,
42 const TextView::LayoutParameters& layoutParameters,
43 TextView::RelayoutData& relayoutData )
45 const float wordOffset = ( relayoutParameters.mIsFirstCharacter ? 0.f : relayoutParameters.mPositionOffset.x );
46 const float previousPositionY = ( relayoutParameters.mIsFirstCharacter ? 0.f : relayoutParameters.mPositionOffset.y );
48 if( ( relayoutParameters.mIsNewLine ||
49 relayoutParameters.mIsFirstCharacter ||
50 ( wordOffset + relayoutParameters.mCharacterSize.width > relayoutData.mTextViewSize.width ) ) )
52 if( !relayoutParameters.mIsNewLine &&
53 ( relayoutParameters.mIsWhiteSpace || relayoutParameters.mIsNewParagraphCharacter ) )
55 // Current character is a white space. Don't want to move a white space to the next line.
56 // These white spaces are placed just in the edge.
57 return Vector3( relayoutData.mTextViewSize.width - relayoutParameters.mWordSize.width, relayoutParameters.mPositionOffset.y, 0.f );
61 // Calculate the line length and the max character height for the current line.
62 TextViewRelayout::LineLayoutInfo subLineInfo;
63 subLineInfo.mLineLength = 0.f;
64 subLineInfo.mMaxCharHeight = 0.f;
65 subLineInfo.mMaxAscender = 0.f;
66 const TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + relayoutParameters.mIndices.mParagraphIndex ) );
68 TextViewRelayout::CalculateLineLayout( relayoutData.mTextViewSize.width,
69 relayoutParameters.mIndices,
71 TextViewRelayout::WrapByCharacter,
75 Toolkit::TextView::LineLayoutInfo lineInfo;
76 lineInfo.mCharacterGlobalIndex = relayoutParameters.mCharacterGlobalIndex; // Index to the first character of the next line.
77 lineInfo.mSize = Size( subLineInfo.mLineLength, subLineInfo.mMaxCharHeight ); // Size of this piece of paragraph.
78 lineInfo.mAscender = subLineInfo.mMaxAscender; // Ascender of this piece of paragraph.
79 relayoutData.mLines.push_back( lineInfo );
81 return Vector3( 0.f, previousPositionY + subLineInfo.mMaxCharHeight + layoutParameters.mLineHeightOffset, 0.f );
86 return Vector3( wordOffset, previousPositionY, 0.f );
90 void CalculateSizeAndPosition( const TextView::LayoutParameters& layoutParameters,
91 TextView::RelayoutData& relayoutData )
93 TextViewRelayout::RelayoutParameters relayoutParameters;
96 relayoutData.mCharacterLayoutInfoTable.clear();
97 relayoutData.mLines.clear();
98 relayoutData.mTextSizeForRelayoutOption = Size();
100 // Calculate the text size for split by char.
101 Vector4 minMaxXY( std::numeric_limits<float>::max(),
102 std::numeric_limits<float>::max(),
103 std::numeric_limits<float>::min(),
104 std::numeric_limits<float>::min() );
106 relayoutData.mShrinkFactor = 1.f; // Shrink factor used when the exceed policy contains ShrinkToFit
108 relayoutParameters.mPositionOffset = Vector3::ZERO;
109 relayoutParameters.mIsFirstCharacter = true;
110 relayoutParameters.mIndices.mParagraphIndex = 0u;
111 relayoutParameters.mCharacterGlobalIndex = 0u;
113 for( TextViewProcessor::ParagraphLayoutInfoContainer::iterator paragraphLayoutIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin(),
114 endParagraphLayoutIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.end();
115 paragraphLayoutIt != endParagraphLayoutIt;
116 ++paragraphLayoutIt, ++relayoutParameters.mIndices.mParagraphIndex )
118 TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *paragraphLayoutIt );
120 relayoutParameters.mIsNewLine = true;
121 relayoutParameters.mParagraphSize = paragraphLayoutInfo.mSize;
122 relayoutParameters.mIndices.mWordIndex = 0u;
124 for( TextViewProcessor::WordLayoutInfoContainer::iterator wordLayoutIt = paragraphLayoutInfo.mWordsLayoutInfo.begin(),
125 endWordLayoutIt = paragraphLayoutInfo.mWordsLayoutInfo.end();
126 wordLayoutIt != endWordLayoutIt;
127 ++wordLayoutIt, ++relayoutParameters.mIndices.mWordIndex )
129 TextViewProcessor::WordLayoutInfo& wordLayoutInfo( *wordLayoutIt );
130 relayoutParameters.mIsWhiteSpace = TextViewProcessor::WordSeparator == wordLayoutInfo.mType;
131 relayoutParameters.mIsNewParagraphCharacter = TextViewProcessor::ParagraphSeparator == wordLayoutInfo.mType;
133 relayoutParameters.mIsFirstCharacterOfWord = true;
134 relayoutParameters.mWordSize = wordLayoutInfo.mSize;
135 relayoutParameters.mIndices.mCharacterIndex = 0u;
137 for( TextViewProcessor::CharacterLayoutInfoContainer::iterator characterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.begin(),
138 endCharacterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.end();
139 characterLayoutIt != endCharacterLayoutIt;
140 ++characterLayoutIt, ++relayoutParameters.mIndices.mCharacterIndex )
142 TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo( *characterLayoutIt );
144 relayoutParameters.mCharacterSize = characterLayoutInfo.mSize;
146 switch( layoutParameters.mExceedPolicy )
148 case TextView::OriginalShrink:
149 case TextView::SplitOriginal:
150 case TextView::SplitFade:
151 case TextView::SplitEllipsizeEnd:
152 case TextView::SplitShrink:
153 case TextView::ShrinkOriginal:
154 case TextView::ShrinkFade:
155 case TextView::Shrink:
156 case TextView::EllipsizeEndOriginal:
157 case TextView::EllipsizeEnd: // Fall Through
159 DALI_LOG_WARNING( "SplitByChar::CalculateSizeAndPosition() policy not implemented.\n" );
162 case TextView::OriginalFade:
163 case TextView::FadeOriginal:
164 case TextView::Original:
165 case TextView::Fade: // Fall Through
167 characterLayoutInfo.mPosition = NoShrinkWhenExceedPosition( relayoutParameters,
171 relayoutParameters.mPositionOffset = characterLayoutInfo.mPosition + Vector3( characterLayoutInfo.mSize.width, 0.f, 0.f );
176 DALI_LOG_WARNING( "SplitByChar::CalculateSizeAndPosition() policy combination not possible.\n" );
180 // Get last line info and calculate the bearing (used to align glyphs with the baseline).
181 TextViewRelayout::CalculateBearing( characterLayoutInfo, relayoutData );
183 // updates min and max position to calculate the text size for split by char.
184 TextViewRelayout::UpdateLayoutInfoTable( minMaxXY,
190 ++relayoutParameters.mCharacterGlobalIndex;
191 relayoutParameters.mIsFirstCharacter = false;
192 relayoutParameters.mIsNewLine = false;
197 if( relayoutData.mCharacterLayoutInfoTable.empty() )
199 relayoutData.mTextSizeForRelayoutOption = Size();
203 relayoutData.mTextSizeForRelayoutOption.width = minMaxXY.z - minMaxXY.x;
204 relayoutData.mTextSizeForRelayoutOption.height = minMaxXY.w - minMaxXY.y;
207 // Check if the last character is a new paragraph character. In that case the height should be added.
208 if( !relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.empty() )
210 const TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.end() - 1u ) );
212 if( paragraphLayoutInfo.mWordsLayoutInfo.empty() ) // if it's empty, it means the last character is a new paragraph character.
214 relayoutData.mTextSizeForRelayoutOption.height += paragraphLayoutInfo.mSize.height;
221 void Relayout( Actor textView,
222 TextView::RelayoutOperationMask relayoutOperationMask,
223 const TextView::LayoutParameters& layoutParameters,
224 const TextView::VisualParameters& visualParameters,
225 TextView::RelayoutData& relayoutData )
227 if( relayoutOperationMask & TextView::RELAYOUT_SIZE_POSITION )
229 CalculateSizeAndPosition( layoutParameters,
232 TextViewRelayout::ReorderRightToLeftLayout( relayoutData );
234 TextViewRelayout::SetUnderlineInfo( relayoutData );
237 if( relayoutOperationMask & TextView::RELAYOUT_ALIGNMENT )
239 TextViewRelayout::UpdateAlignment( layoutParameters,
243 if( relayoutOperationMask & TextView::RELAYOUT_VISIBILITY )
245 TextViewRelayout::UpdateVisibility( layoutParameters,
250 const bool initializeTextActors = relayoutOperationMask & TextView::RELAYOUT_INITIALIZE_TEXT_ACTORS;
251 const bool updateTextActors = relayoutOperationMask & TextView::RELAYOUT_TEXT_ACTOR_UPDATE;
252 if( initializeTextActors || updateTextActors )
254 TextViewRelayout::UpdateTextActorInfo( visualParameters,
256 initializeTextActors );
259 if( relayoutOperationMask & TextView::RELAYOUT_INSERT_TO_TEXT_VIEW )
261 TextViewRelayout::InsertToTextView( textView,
266 } // namespace SplitByChar
268 } // namespace Internal
270 } // namespace Toolkit