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-new-line-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>
35 namespace SplitByNewLineChar
41 Vector3 SplitPosition( 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 const TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + relayoutParameters.mIndices.mParagraphIndex ) );
63 TextViewRelayout::LineLayoutInfo subLineInfo;
64 subLineInfo.mLineLength = 0.f;
65 subLineInfo.mMaxCharHeight = 0.f;
66 subLineInfo.mMaxAscender = 0.f;
67 TextViewRelayout::CalculateLineLayout( relayoutData.mTextViewSize.width,
68 relayoutParameters.mIndices,
70 TextViewRelayout::WrapByParagraphCharacterAndSplit,
74 Toolkit::TextView::LineLayoutInfo lineInfo;
75 lineInfo.mCharacterGlobalIndex = relayoutParameters.mCharacterGlobalIndex; // Index to the first character of the next line.
76 lineInfo.mSize = Size( subLineInfo.mLineLength, subLineInfo.mMaxCharHeight ); // Size of this piece of paragraph.
77 lineInfo.mAscender = subLineInfo.mMaxAscender; // Ascender of this piece of paragraph.
78 relayoutData.mLines.push_back( lineInfo );
80 return Vector3( 0.f, previousPositionY + subLineInfo.mMaxCharHeight + layoutParameters.mLineHeightOffset, 0.f );
85 return Vector3( wordOffset, previousPositionY, 0.f );
89 void CalculateSizeAndPosition( const TextView::LayoutParameters& layoutParameters,
90 TextView::RelayoutData& relayoutData )
93 relayoutData.mCharacterLayoutInfoTable.clear();
94 relayoutData.mLines.clear();
95 relayoutData.mTextSizeForRelayoutOption = Size();
96 relayoutData.mShrinkFactor = 1.f;
98 // Calculates the text size for split by char.
99 Vector4 minMaxXY( std::numeric_limits<float>::max(),
100 std::numeric_limits<float>::max(),
101 std::numeric_limits<float>::min(),
102 std::numeric_limits<float>::min() );
104 TextViewRelayout::RelayoutParameters relayoutParameters;
106 if( TextView::ShrinkOriginal == layoutParameters.mExceedPolicy )
108 if( relayoutData.mTextLayoutInfo.mWholeTextSize.width > relayoutData.mTextViewSize.width )
110 relayoutData.mShrinkFactor = relayoutData.mTextViewSize.width / relayoutData.mTextLayoutInfo.mWholeTextSize.width;
113 else if( TextView::Shrink == layoutParameters.mExceedPolicy )
115 if( ( relayoutData.mTextLayoutInfo.mWholeTextSize.width > relayoutData.mTextViewSize.width ) ||
116 ( relayoutData.mTextLayoutInfo.mWholeTextSize.height > relayoutData.mTextViewSize.height ) )
118 relayoutData.mShrinkFactor = std::min( relayoutData.mTextViewSize.width / relayoutData.mTextLayoutInfo.mWholeTextSize.width,
119 relayoutData.mTextViewSize.height / relayoutData.mTextLayoutInfo.mWholeTextSize.height );
123 relayoutParameters.mIsFirstCharacter = true;
124 relayoutParameters.mIndices.mParagraphIndex = 0u;
125 relayoutParameters.mPositionOffset = Vector3::ZERO;
126 relayoutParameters.mCharacterGlobalIndex = 0u;
128 for( TextViewProcessor::ParagraphLayoutInfoContainer::iterator paragraphLayoutIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin(),
129 endParagraphLayoutIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.end();
130 paragraphLayoutIt != endParagraphLayoutIt;
131 ++paragraphLayoutIt, ++relayoutParameters.mIndices.mParagraphIndex )
133 TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *paragraphLayoutIt );
135 relayoutParameters.mParagraphSize = paragraphLayoutInfo.mSize * relayoutData.mShrinkFactor;
137 relayoutParameters.mIsNewLine = true;
138 relayoutParameters.mIndices.mWordIndex = 0u;
140 for( TextViewProcessor::WordLayoutInfoContainer::iterator wordLayoutIt = paragraphLayoutInfo.mWordsLayoutInfo.begin(),
141 endWordLayoutIt = paragraphLayoutInfo.mWordsLayoutInfo.end();
142 wordLayoutIt != endWordLayoutIt;
143 ++wordLayoutIt, ++relayoutParameters.mIndices.mWordIndex )
145 TextViewProcessor::WordLayoutInfo& wordLayoutInfo( *wordLayoutIt );
146 relayoutParameters.mIsWhiteSpace = TextViewProcessor::WordSeparator == wordLayoutInfo.mType;
147 relayoutParameters.mIsNewParagraphCharacter = TextViewProcessor::ParagraphSeparator == wordLayoutInfo.mType;
149 relayoutParameters.mIsFirstCharacterOfWord = true;
150 relayoutParameters.mWordSize = wordLayoutInfo.mSize;
151 relayoutParameters.mIndices.mCharacterIndex = 0u;
153 for( TextViewProcessor::CharacterLayoutInfoContainer::iterator characterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.begin(),
154 endCharacterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.end();
155 characterLayoutIt != endCharacterLayoutIt;
156 ++characterLayoutIt, ++relayoutParameters.mIndices.mCharacterIndex )
158 TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo( *characterLayoutIt );
159 relayoutParameters.mCharacterSize = characterLayoutInfo.mSize;
161 relayoutParameters.mCharacterSize = characterLayoutInfo.mSize;
163 switch( layoutParameters.mExceedPolicy )
165 case TextView::OriginalShrink:
166 case TextView::SplitShrink:
167 case TextView::ShrinkFade: // Fall Through
169 DALI_LOG_WARNING( "SplitByNewLineChar::CalculateSizeAndPosition() policy not implemented.\n" );
172 case TextView::Original: // Fall Through
173 case TextView::ShrinkOriginal: // Fall Through
174 case TextView::Shrink: // Fall Through
175 case TextView::OriginalFade: // Fall Through
176 case TextView::FadeOriginal: // Fall Through
177 case TextView::Fade: // Fall Through
178 case TextView::EllipsizeEndOriginal: // Fall Through
179 case TextView::EllipsizeEnd: // Fall Through
181 if( relayoutParameters.mIsNewLine )
183 relayoutParameters.mPositionOffset.x = 0.f;
184 relayoutParameters.mPositionOffset.y += paragraphLayoutInfo.mSize.height * relayoutData.mShrinkFactor;
187 characterLayoutInfo.mPosition = relayoutParameters.mPositionOffset;
189 relayoutParameters.mPositionOffset.x += characterLayoutInfo.mSize.width * relayoutData.mShrinkFactor;
191 if( relayoutParameters.mIsNewLine ||
192 relayoutParameters.mIsFirstCharacter )
194 Toolkit::TextView::LineLayoutInfo lineInfo;
195 lineInfo.mCharacterGlobalIndex = relayoutParameters.mCharacterGlobalIndex; // Index to the first character of the next line.
196 lineInfo.mSize = relayoutParameters.mParagraphSize; // Size of this piece of paragraph.
197 lineInfo.mAscender = paragraphLayoutInfo.mAscender * relayoutData.mShrinkFactor; // Ascender of this piece of paragraph.
198 relayoutData.mLines.push_back( lineInfo );
202 case TextView::SplitOriginal:
203 case TextView::SplitFade:
204 case TextView::SplitEllipsizeEnd: // Fall Through
206 characterLayoutInfo.mPosition = SplitPosition( relayoutParameters,
210 relayoutParameters.mPositionOffset = characterLayoutInfo.mPosition + Vector3( characterLayoutInfo.mSize.width, 0.f, 0.f );
215 DALI_LOG_WARNING( "SplitByNewLineChar::CalculateSizeAndPosition() Layout configuration not possible.\n" );
220 // Get last line info and calculate the bearing (used to align glyphs with the baseline).
221 TextViewRelayout::CalculateBearing( characterLayoutInfo, relayoutData );
223 // updates min and max position to calculate the text size for split by new line char.
224 TextViewRelayout::UpdateLayoutInfoTable( minMaxXY,
230 ++relayoutParameters.mCharacterGlobalIndex;
231 relayoutParameters.mIsFirstCharacter = false;
232 relayoutParameters.mIsNewLine = false;
237 if( relayoutData.mCharacterLayoutInfoTable.empty() )
239 relayoutData.mTextSizeForRelayoutOption = Size();
243 relayoutData.mTextSizeForRelayoutOption.width = minMaxXY.z - minMaxXY.x;
244 relayoutData.mTextSizeForRelayoutOption.height = minMaxXY.w - minMaxXY.y;
247 // Check if the last character is a new paragraph character. In that case the height should be added.
248 if( !relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.empty() )
250 const TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.end() - 1u ) );
252 if( paragraphLayoutInfo.mWordsLayoutInfo.empty() ) // if it's empty, it means the last character is a new paragraph character.
254 relayoutData.mTextSizeForRelayoutOption.height += paragraphLayoutInfo.mSize.height * relayoutData.mShrinkFactor;
261 void Relayout( Actor textView,
262 TextView::RelayoutOperationMask relayoutOperationMask,
263 const TextView::LayoutParameters& layoutParameters,
264 const TextView::VisualParameters& visualParameters,
265 TextView::RelayoutData& relayoutData )
267 if( relayoutOperationMask & TextView::RELAYOUT_SIZE_POSITION )
269 CalculateSizeAndPosition( layoutParameters,
272 TextViewRelayout::ReorderRightToLeftLayout( relayoutData );
274 TextViewRelayout::SetUnderlineInfo( relayoutData );
277 if( relayoutOperationMask & TextView::RELAYOUT_ALIGNMENT )
279 TextViewRelayout::UpdateAlignment( layoutParameters,
283 if( relayoutOperationMask & TextView::RELAYOUT_VISIBILITY )
285 TextViewRelayout::UpdateVisibility( layoutParameters,
290 const bool initializeTextActors = relayoutOperationMask & TextView::RELAYOUT_INITIALIZE_TEXT_ACTORS;
291 const bool updateTextActors = relayoutOperationMask & TextView::RELAYOUT_TEXT_ACTOR_UPDATE;
292 if( initializeTextActors || updateTextActors )
294 TextViewRelayout::UpdateTextActorInfo( visualParameters,
296 initializeTextActors );
299 if( relayoutOperationMask & TextView::RELAYOUT_INSERT_TO_TEXT_VIEW )
301 TextViewRelayout::InsertToTextView( textView,
306 } // namespace SplitByNewLineChar
308 } // namespace Internal
310 } // namespace Toolkit