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>
25 #include <dali-toolkit/internal/controls/text-view/relayout-utilities.h>
26 #include <dali-toolkit/internal/controls/text-view/text-view-processor.h>
43 Vector3 NoShrinkWhenExceedPosition( const TextViewRelayout::RelayoutParameters& relayoutParameters,
44 const TextView::LayoutParameters& layoutParameters,
45 TextView::RelayoutData& relayoutData )
47 const float wordOffset = ( relayoutParameters.mIsFirstCharacter ? 0.f : relayoutParameters.mPositionOffset.x );
48 const float previousPositionY = ( relayoutParameters.mIsFirstCharacter ? 0.f : relayoutParameters.mPositionOffset.y );
50 if( ( relayoutParameters.mIsNewLine ||
51 relayoutParameters.mIsFirstCharacter ||
52 ( wordOffset + relayoutParameters.mCharacterSize.width > relayoutData.mTextViewSize.width ) ) )
54 if( !relayoutParameters.mIsNewLine &&
55 ( relayoutParameters.mIsWhiteSpace || relayoutParameters.mIsNewParagraphCharacter ) )
57 // Current character is a white space. Don't want to move a white space to the next line.
58 // These white spaces are placed just in the edge.
59 return Vector3( relayoutData.mTextViewSize.width - relayoutParameters.mWordSize.width, relayoutParameters.mPositionOffset.y, 0.f );
63 // Calculate the line length and the max character height for the current line.
64 TextViewRelayout::LineLayoutInfo subLineInfo;
65 subLineInfo.mLineLength = 0.f;
66 subLineInfo.mMaxCharHeight = 0.f;
67 subLineInfo.mMaxAscender = 0.f;
68 const TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin() + relayoutParameters.mIndices.mParagraphIndex ) );
70 TextViewRelayout::CalculateLineLayout( relayoutData.mTextViewSize.width,
71 relayoutParameters.mIndices,
73 TextViewRelayout::WrapByCharacter,
77 Toolkit::TextView::LineLayoutInfo lineInfo;
78 lineInfo.mCharacterGlobalIndex = relayoutParameters.mCharacterGlobalIndex; // Index to the first character of the next line.
79 lineInfo.mSize = Size( subLineInfo.mLineLength, subLineInfo.mMaxCharHeight ); // Size of this piece of paragraph.
80 lineInfo.mAscender = subLineInfo.mMaxAscender; // Ascender of this piece of paragraph.
81 relayoutData.mLines.push_back( lineInfo );
83 return Vector3( 0.f, previousPositionY + subLineInfo.mMaxCharHeight + layoutParameters.mLineHeightOffset, 0.f );
88 return Vector3( wordOffset, previousPositionY, 0.f );
92 void CalculateSizeAndPosition( const TextView::LayoutParameters& layoutParameters,
93 TextView::RelayoutData& relayoutData )
95 TextViewRelayout::RelayoutParameters relayoutParameters;
98 relayoutData.mCharacterLayoutInfoTable.clear();
99 relayoutData.mLines.clear();
100 relayoutData.mTextSizeForRelayoutOption = Size();
102 // Calculate the text size for split by char.
103 Vector4 minMaxXY( std::numeric_limits<float>::max(),
104 std::numeric_limits<float>::max(),
105 std::numeric_limits<float>::min(),
106 std::numeric_limits<float>::min() );
108 relayoutData.mShrinkFactor = 1.f; // Shrink factor used when the exceed policy contains ShrinkToFit
110 relayoutParameters.mPositionOffset = Vector3::ZERO;
111 relayoutParameters.mIsFirstCharacter = true;
112 relayoutParameters.mIndices.mParagraphIndex = 0u;
113 relayoutParameters.mCharacterGlobalIndex = 0u;
115 for( TextViewProcessor::ParagraphLayoutInfoContainer::iterator paragraphLayoutIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.begin(),
116 endParagraphLayoutIt = relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.end();
117 paragraphLayoutIt != endParagraphLayoutIt;
118 ++paragraphLayoutIt, ++relayoutParameters.mIndices.mParagraphIndex )
120 TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *paragraphLayoutIt );
122 relayoutParameters.mIsNewLine = true;
123 relayoutParameters.mParagraphSize = paragraphLayoutInfo.mSize;
124 relayoutParameters.mIndices.mWordIndex = 0u;
126 for( TextViewProcessor::WordLayoutInfoContainer::iterator wordLayoutIt = paragraphLayoutInfo.mWordsLayoutInfo.begin(),
127 endWordLayoutIt = paragraphLayoutInfo.mWordsLayoutInfo.end();
128 wordLayoutIt != endWordLayoutIt;
129 ++wordLayoutIt, ++relayoutParameters.mIndices.mWordIndex )
131 TextViewProcessor::WordLayoutInfo& wordLayoutInfo( *wordLayoutIt );
132 relayoutParameters.mIsWhiteSpace = TextViewProcessor::WordSeparator == wordLayoutInfo.mType;
133 relayoutParameters.mIsNewParagraphCharacter = TextViewProcessor::ParagraphSeparator == wordLayoutInfo.mType;
135 relayoutParameters.mIsFirstCharacterOfWord = true;
136 relayoutParameters.mWordSize = wordLayoutInfo.mSize;
137 relayoutParameters.mIndices.mCharacterIndex = 0u;
139 for( TextViewProcessor::CharacterLayoutInfoContainer::iterator characterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.begin(),
140 endCharacterLayoutIt = wordLayoutInfo.mCharactersLayoutInfo.end();
141 characterLayoutIt != endCharacterLayoutIt;
142 ++characterLayoutIt, ++relayoutParameters.mIndices.mCharacterIndex )
144 TextViewProcessor::CharacterLayoutInfo& characterLayoutInfo( *characterLayoutIt );
146 relayoutParameters.mCharacterSize = characterLayoutInfo.mSize;
148 switch( layoutParameters.mExceedPolicy )
150 case TextView::OriginalShrink:
151 case TextView::SplitOriginal:
152 case TextView::SplitFade:
153 case TextView::SplitEllipsizeEnd:
154 case TextView::SplitShrink:
155 case TextView::ShrinkOriginal:
156 case TextView::ShrinkFade:
157 case TextView::Shrink:
158 case TextView::EllipsizeEndOriginal:
159 case TextView::EllipsizeEnd: // Fall Through
161 DALI_LOG_WARNING( "SplitByChar::CalculateSizeAndPosition() policy not implemented.\n" );
164 case TextView::OriginalFade:
165 case TextView::FadeOriginal:
166 case TextView::Original:
167 case TextView::Fade: // Fall Through
169 characterLayoutInfo.mPosition = NoShrinkWhenExceedPosition( relayoutParameters,
173 relayoutParameters.mPositionOffset = characterLayoutInfo.mPosition + Vector3( characterLayoutInfo.mSize.width, 0.f, 0.f );
178 DALI_LOG_WARNING( "SplitByChar::CalculateSizeAndPosition() policy combination not possible.\n" );
182 // Get last line info and calculate the bearing (used to align glyphs with the baseline).
183 TextViewRelayout::CalculateBearing( characterLayoutInfo, relayoutData );
185 // updates min and max position to calculate the text size for split by char.
186 TextViewRelayout::UpdateLayoutInfoTable( minMaxXY,
192 ++relayoutParameters.mCharacterGlobalIndex;
193 relayoutParameters.mIsFirstCharacter = false;
194 relayoutParameters.mIsNewLine = false;
199 if( relayoutData.mCharacterLayoutInfoTable.empty() )
201 relayoutData.mTextSizeForRelayoutOption = Size();
205 relayoutData.mTextSizeForRelayoutOption.width = minMaxXY.z - minMaxXY.x;
206 relayoutData.mTextSizeForRelayoutOption.height = minMaxXY.w - minMaxXY.y;
209 // Check if the last character is a new paragraph character. In that case the height should be added.
210 if( !relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.empty() )
212 const TextViewProcessor::ParagraphLayoutInfo& paragraphLayoutInfo( *( relayoutData.mTextLayoutInfo.mParagraphsLayoutInfo.end() - 1u ) );
214 if( paragraphLayoutInfo.mWordsLayoutInfo.empty() ) // if it's empty, it means the last character is a new paragraph character.
216 relayoutData.mTextSizeForRelayoutOption.height += paragraphLayoutInfo.mSize.height;
223 void Relayout( Actor textView,
224 TextView::RelayoutOperationMask relayoutOperationMask,
225 const TextView::LayoutParameters& layoutParameters,
226 const TextView::VisualParameters& visualParameters,
227 TextView::RelayoutData& relayoutData )
229 if( relayoutOperationMask & TextView::RELAYOUT_SIZE_POSITION )
231 CalculateSizeAndPosition( layoutParameters,
234 TextViewRelayout::ReorderRightToLeftLayout( relayoutData );
236 TextViewRelayout::SetUnderlineInfo( relayoutData );
239 if( relayoutOperationMask & TextView::RELAYOUT_ALIGNMENT )
241 TextViewRelayout::UpdateAlignment( layoutParameters,
245 if( relayoutOperationMask & TextView::RELAYOUT_VISIBILITY )
247 TextViewRelayout::UpdateVisibility( layoutParameters,
252 const bool initializeTextActors = relayoutOperationMask & TextView::RELAYOUT_INITIALIZE_TEXT_ACTORS;
253 const bool updateTextActors = relayoutOperationMask & TextView::RELAYOUT_TEXT_ACTOR_UPDATE;
254 if( initializeTextActors || updateTextActors )
256 TextViewRelayout::UpdateTextActorInfo( visualParameters,
258 initializeTextActors );
261 if( relayoutOperationMask & TextView::RELAYOUT_INSERT_TO_TEXT_VIEW )
263 TextViewRelayout::InsertToTextView( textView,
268 } // namespace SplitByChar
270 } // namespace Internal
272 } // namespace Toolkit