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.mIsNewLineCharacter ) )
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::SubLineLayoutInfo subLineInfo;
63 subLineInfo.mLineLength = 0.f;
64 subLineInfo.mMaxCharHeight = 0.f;
65 subLineInfo.mMaxAscender = 0.f;
66 const TextViewProcessor::LineLayoutInfo& lineLayoutInfo( *( relayoutData.mTextLayoutInfo.mLinesLayoutInfo.begin() + relayoutParameters.mIndices.mLineIndex ) );
68 TextViewRelayout::CalculateSubLineLayout( relayoutData.mTextViewSize.width,
69 relayoutParameters.mIndices,
71 TextViewRelayout::WrapByCharacter,
75 // Stores some info to calculate the line justification in a post-process.
76 TextView::LineJustificationInfo justificationInfo;
78 justificationInfo.mIndices = relayoutParameters.mIndices;
79 justificationInfo.mLineLength = subLineInfo.mLineLength;
81 relayoutData.mLineJustificationInfo.push_back( justificationInfo );
83 Toolkit::TextView::LineLayoutInfo lineInfo;
84 lineInfo.mCharacterGlobalIndex = relayoutParameters.mCharacterGlobalIndex; // Index to the first character of the next line.
85 lineInfo.mSize = Size( subLineInfo.mLineLength, subLineInfo.mMaxCharHeight ); // Size of this piece of line.
86 lineInfo.mAscender = subLineInfo.mMaxAscender; // Ascender of this piece of line.
87 relayoutData.mLines.push_back( lineInfo );
89 return Vector3( 0.f, previousPositionY + subLineInfo.mMaxCharHeight + layoutParameters.mLineHeightOffset, 0.f );
94 return Vector3( wordOffset, previousPositionY, 0.f );
98 void CalculateSizeAndPosition( const TextView::LayoutParameters& layoutParameters,
99 TextView::RelayoutData& relayoutData )
101 TextViewRelayout::RelayoutParameters relayoutParameters;
104 relayoutData.mCharacterLayoutInfoTable.clear();
105 relayoutData.mLines.clear();
106 relayoutData.mTextSizeForRelayoutOption = Size();
108 // Calculate the text size for split by char.
109 Vector4 minMaxXY( std::numeric_limits<float>::max(),
110 std::numeric_limits<float>::max(),
111 std::numeric_limits<float>::min(),
112 std::numeric_limits<float>::min() );
114 relayoutData.mShrinkFactor = 1.f; // Shrink factor used when the exceed policy contains ShrinkToFit
116 relayoutParameters.mPositionOffset = Vector3::ZERO;
117 relayoutParameters.mIsFirstCharacter = true;
118 relayoutParameters.mIndices.mLineIndex = 0u;
119 relayoutParameters.mCharacterGlobalIndex = 0u;
121 for( TextViewProcessor::LineLayoutInfoContainer::iterator lineLayoutIt = relayoutData.mTextLayoutInfo.mLinesLayoutInfo.begin(),
122 endLineLayoutIt = relayoutData.mTextLayoutInfo.mLinesLayoutInfo.end();
123 lineLayoutIt != endLineLayoutIt;
124 ++lineLayoutIt, ++relayoutParameters.mIndices.mLineIndex )
126 TextViewProcessor::LineLayoutInfo& lineLayoutInfo( *lineLayoutIt );
128 relayoutParameters.mIsNewLine = true;
129 relayoutParameters.mLineSize = lineLayoutInfo.mSize;
130 relayoutParameters.mIndices.mWordIndex = 0u;
132 for( TextViewProcessor::WordLayoutInfoContainer::iterator wordLayoutIt = lineLayoutInfo.mWordsLayoutInfo.begin(),
133 endWordLayoutIt = lineLayoutInfo.mWordsLayoutInfo.end();
134 wordLayoutIt != endWordLayoutIt;
135 ++wordLayoutIt, ++relayoutParameters.mIndices.mWordIndex )
137 TextViewProcessor::WordLayoutInfo& wordLayoutInfo( *wordLayoutIt );
138 relayoutParameters.mIsWhiteSpace = TextViewProcessor::WordSeparator == wordLayoutInfo.mType;
139 relayoutParameters.mIsNewLineCharacter = TextViewProcessor::LineSeparator == wordLayoutInfo.mType;
141 relayoutParameters.mIsFirstCharacterOfWord = true;
142 relayoutParameters.mWordSize = wordLayoutInfo.mSize;
143 relayoutParameters.mIndices.mCharacterIndex = 0u;
145 for( TextViewProcessor::CharacterLayoutInfoContainer::iterator characterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.begin(),
146 endCharacterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.end();
147 characterLayoutIt != endCharacterLayoutIt;
148 ++characterLayoutIt, ++relayoutParameters.mIndices.mCharacterIndex )
150 TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo( *characterLayoutIt );
152 relayoutParameters.mCharacterSize = characterLayoutInfo.mSize;
154 switch( layoutParameters.mExceedPolicy )
156 case TextView::OriginalShrink:
157 case TextView::SplitOriginal:
158 case TextView::SplitFade:
159 case TextView::SplitEllipsizeEnd:
160 case TextView::SplitShrink:
161 case TextView::ShrinkOriginal:
162 case TextView::ShrinkFade:
163 case TextView::Shrink:
164 case TextView::EllipsizeEndOriginal:
165 case TextView::EllipsizeEnd: // Fall Through
167 DALI_LOG_WARNING( "SplitByChar::CalculateSizeAndPosition() policy not implemented.\n" );
170 case TextView::OriginalFade:
171 case TextView::FadeOriginal:
172 case TextView::Original:
173 case TextView::Fade: // Fall Through
175 characterLayoutInfo.mPosition = NoShrinkWhenExceedPosition( relayoutParameters,
179 relayoutParameters.mPositionOffset = characterLayoutInfo.mPosition + Vector3( characterLayoutInfo.mSize.width, 0.f, 0.f );
184 DALI_LOG_WARNING( "SplitByChar::CalculateSizeAndPosition() policy combination not possible.\n" );
188 // Get last line info and calculate the bearing (used to align glyphs with the baseline).
189 TextViewRelayout::CalculateBearing( characterLayoutInfo, relayoutData );
191 // updates min and max position to calculate the text size for split by char.
192 TextViewRelayout::UpdateLayoutInfoTable( minMaxXY,
198 ++relayoutParameters.mCharacterGlobalIndex;
199 relayoutParameters.mIsFirstCharacter = false;
200 relayoutParameters.mIsNewLine = false;
205 if( relayoutData.mCharacterLayoutInfoTable.empty() )
207 relayoutData.mTextSizeForRelayoutOption = Size();
211 relayoutData.mTextSizeForRelayoutOption.width = minMaxXY.z - minMaxXY.x;
212 relayoutData.mTextSizeForRelayoutOption.height = minMaxXY.w - minMaxXY.y;
215 // Check if the last character is a new line character. In that case the height should be added.
216 if( !relayoutData.mTextLayoutInfo.mLinesLayoutInfo.empty() )
218 const TextViewProcessor::LineLayoutInfo& lineLayoutInfo( *( relayoutData.mTextLayoutInfo.mLinesLayoutInfo.end() - 1u ) );
220 if( lineLayoutInfo.mWordsLayoutInfo.empty() ) // if it's empty, it means the last character is a new line character.
222 relayoutData.mTextSizeForRelayoutOption.height += lineLayoutInfo.mSize.height;
229 void Relayout( Actor textView,
230 TextView::RelayoutOperationMask relayoutOperationMask,
231 const TextView::LayoutParameters& layoutParameters,
232 const TextView::VisualParameters& visualParameters,
233 TextView::RelayoutData& relayoutData )
235 if( relayoutOperationMask & TextView::RELAYOUT_SIZE_POSITION )
237 relayoutData.mLineJustificationInfo.clear();
238 CalculateSizeAndPosition( layoutParameters,
241 TextViewRelayout::SetUnderlineInfo( relayoutData );
244 if( relayoutOperationMask & TextView::RELAYOUT_ALIGNMENT )
246 TextViewRelayout::UpdateAlignment( layoutParameters,
250 if( relayoutOperationMask & TextView::RELAYOUT_VISIBILITY )
252 TextViewRelayout::UpdateVisibility( layoutParameters,
257 const bool initializeTextActors = relayoutOperationMask & TextView::RELAYOUT_INITIALIZE_TEXT_ACTORS;
258 const bool updateTextActors = relayoutOperationMask & TextView::RELAYOUT_TEXT_ACTOR_UPDATE;
259 if( initializeTextActors || updateTextActors )
261 TextViewRelayout::UpdateTextActorInfo( visualParameters,
263 initializeTextActors );
266 if( relayoutOperationMask & TextView::RELAYOUT_INSERT_TO_TEXT_VIEW )
268 TextViewRelayout::InsertToTextView( textView,
273 } // namespace SplitByChar
275 } // namespace Internal
277 } // namespace Toolkit