2 * Copyright (c) 2022 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/text/controller/text-controller-impl-data-clearer.h>
22 #include <dali-toolkit/internal/text/controller/text-controller-impl.h>
23 #include <dali-toolkit/internal/text/text-run-container.h>
25 namespace Dali::Toolkit::Text
28 void ControllerImplDataClearer::ClearFullModelData(Controller::Impl& impl, Controller::OperationsMask operations)
30 ModelPtr& model = impl.mModel;
32 if(Controller::NO_OPERATION != (Controller::GET_LINE_BREAKS & operations))
34 model->mLogicalModel->mLineBreakInfo.Clear();
35 model->mLogicalModel->mParagraphInfo.Clear();
38 if(Controller::NO_OPERATION != (Controller::GET_SCRIPTS & operations))
40 model->mLogicalModel->mScriptRuns.Clear();
43 if(Controller::NO_OPERATION != (Controller::VALIDATE_FONTS & operations))
45 model->mLogicalModel->mFontRuns.Clear();
48 if(0u != model->mLogicalModel->mBidirectionalParagraphInfo.Count())
50 if(Controller::NO_OPERATION != (Controller::BIDI_INFO & operations))
52 model->mLogicalModel->mBidirectionalParagraphInfo.Clear();
53 model->mLogicalModel->mCharacterDirections.Clear();
56 if(Controller::NO_OPERATION != (Controller::REORDER & operations))
58 // Free the allocated memory used to store the conversion table in the bidirectional line info run.
59 for(Vector<BidirectionalLineInfoRun>::Iterator it = model->mLogicalModel->mBidirectionalLineInfo.Begin(),
60 endIt = model->mLogicalModel->mBidirectionalLineInfo.End();
64 BidirectionalLineInfoRun& bidiLineInfo = *it;
66 free(bidiLineInfo.visualToLogicalMap);
67 bidiLineInfo.visualToLogicalMap = NULL;
69 model->mLogicalModel->mBidirectionalLineInfo.Clear();
73 if(Controller::NO_OPERATION != (Controller::SHAPE_TEXT & operations))
75 model->mVisualModel->mGlyphs.Clear();
76 model->mVisualModel->mGlyphsToCharacters.Clear();
77 model->mVisualModel->mCharactersToGlyph.Clear();
78 model->mVisualModel->mCharactersPerGlyph.Clear();
79 model->mVisualModel->mGlyphsPerCharacter.Clear();
80 model->mVisualModel->mGlyphPositions.Clear();
83 if(Controller::NO_OPERATION != (Controller::LAYOUT & operations))
85 model->mVisualModel->mLines.Clear();
88 if(Controller::NO_OPERATION != (Controller::COLOR & operations))
90 model->mVisualModel->mColorIndices.Clear();
91 model->mVisualModel->mBackgroundColorIndices.Clear();
95 void ControllerImplDataClearer::ClearCharacterModelData(Controller::Impl& impl, CharacterIndex startIndex, CharacterIndex endIndex, Controller::OperationsMask operations)
97 const CharacterIndex endIndexPlusOne = endIndex + 1u;
98 ModelPtr& model = impl.mModel;
100 if(Controller::NO_OPERATION != (Controller::GET_LINE_BREAKS & operations))
102 // Clear the line break info.
103 LineBreakInfo* lineBreakInfoBuffer = model->mLogicalModel->mLineBreakInfo.Begin();
105 model->mLogicalModel->mLineBreakInfo.Erase(lineBreakInfoBuffer + startIndex,
106 lineBreakInfoBuffer + endIndexPlusOne);
108 // Clear the paragraphs.
109 ClearCharacterRuns(startIndex,
111 model->mLogicalModel->mParagraphInfo);
114 if(Controller::NO_OPERATION != (Controller::GET_SCRIPTS & operations))
116 // Clear the scripts.
117 ClearCharacterRuns(startIndex,
119 model->mLogicalModel->mScriptRuns);
122 if(Controller::NO_OPERATION != (Controller::VALIDATE_FONTS & operations))
125 ClearCharacterRuns(startIndex,
127 model->mLogicalModel->mFontRuns);
130 if(0u != model->mLogicalModel->mBidirectionalParagraphInfo.Count())
132 if(Controller::NO_OPERATION != (Controller::BIDI_INFO & operations))
134 // Clear the bidirectional paragraph info.
135 ClearCharacterRuns(startIndex,
137 model->mLogicalModel->mBidirectionalParagraphInfo);
139 // Clear the character's directions.
140 CharacterDirection* characterDirectionsBuffer = model->mLogicalModel->mCharacterDirections.Begin();
142 model->mLogicalModel->mCharacterDirections.Erase(characterDirectionsBuffer + startIndex,
143 characterDirectionsBuffer + endIndexPlusOne);
146 if(Controller::NO_OPERATION != (Controller::REORDER & operations))
148 uint32_t startRemoveIndex = model->mLogicalModel->mBidirectionalLineInfo.Count();
149 uint32_t endRemoveIndex = startRemoveIndex;
150 ClearCharacterRuns(startIndex,
152 model->mLogicalModel->mBidirectionalLineInfo,
156 BidirectionalLineInfoRun* bidirectionalLineInfoBuffer = model->mLogicalModel->mBidirectionalLineInfo.Begin();
158 // Free the allocated memory used to store the conversion table in the bidirectional line info run.
159 for(Vector<BidirectionalLineInfoRun>::Iterator it = bidirectionalLineInfoBuffer + startRemoveIndex,
160 endIt = bidirectionalLineInfoBuffer + endRemoveIndex;
164 BidirectionalLineInfoRun& bidiLineInfo = *it;
166 free(bidiLineInfo.visualToLogicalMap);
167 bidiLineInfo.visualToLogicalMap = NULL;
170 model->mLogicalModel->mBidirectionalLineInfo.Erase(bidirectionalLineInfoBuffer + startRemoveIndex,
171 bidirectionalLineInfoBuffer + endRemoveIndex);
176 void ControllerImplDataClearer::ClearGlyphModelData(Controller::Impl& impl, CharacterIndex startIndex, CharacterIndex endIndex, Controller::OperationsMask operations)
178 const CharacterIndex endIndexPlusOne = endIndex + 1u;
179 const Length numberOfCharactersRemoved = endIndexPlusOne - startIndex;
180 ModelPtr& model = impl.mModel;
181 TextUpdateInfo& textUpdateInfo = impl.mTextUpdateInfo;
184 // Convert the character index to glyph index before deleting the character to glyph and the glyphs per character buffers.
185 GlyphIndex* charactersToGlyphBuffer = model->mVisualModel->mCharactersToGlyph.Begin();
186 Length* glyphsPerCharacterBuffer = model->mVisualModel->mGlyphsPerCharacter.Begin();
188 const GlyphIndex endGlyphIndexPlusOne = *(charactersToGlyphBuffer + endIndex) + *(glyphsPerCharacterBuffer + endIndex);
189 const Length numberOfGlyphsRemoved = endGlyphIndexPlusOne - textUpdateInfo.mStartGlyphIndex;
191 if(Controller::NO_OPERATION != (Controller::SHAPE_TEXT & operations))
193 // Update the character to glyph indices.
194 for(Vector<GlyphIndex>::Iterator it = charactersToGlyphBuffer + endIndexPlusOne,
195 endIt = charactersToGlyphBuffer + model->mVisualModel->mCharactersToGlyph.Count();
199 CharacterIndex& index = *it;
200 index -= numberOfGlyphsRemoved;
203 // Clear the character to glyph conversion table.
204 model->mVisualModel->mCharactersToGlyph.Erase(charactersToGlyphBuffer + startIndex,
205 charactersToGlyphBuffer + endIndexPlusOne);
207 // Clear the glyphs per character table.
208 model->mVisualModel->mGlyphsPerCharacter.Erase(glyphsPerCharacterBuffer + startIndex,
209 glyphsPerCharacterBuffer + endIndexPlusOne);
211 // Clear the glyphs buffer.
212 GlyphInfo* glyphsBuffer = model->mVisualModel->mGlyphs.Begin();
213 model->mVisualModel->mGlyphs.Erase(glyphsBuffer + textUpdateInfo.mStartGlyphIndex,
214 glyphsBuffer + endGlyphIndexPlusOne);
216 CharacterIndex* glyphsToCharactersBuffer = model->mVisualModel->mGlyphsToCharacters.Begin();
218 // Update the glyph to character indices.
219 for(Vector<CharacterIndex>::Iterator it = glyphsToCharactersBuffer + endGlyphIndexPlusOne,
220 endIt = glyphsToCharactersBuffer + model->mVisualModel->mGlyphsToCharacters.Count();
224 CharacterIndex& index = *it;
225 index -= numberOfCharactersRemoved;
228 // Clear the glyphs to characters buffer.
229 model->mVisualModel->mGlyphsToCharacters.Erase(glyphsToCharactersBuffer + textUpdateInfo.mStartGlyphIndex,
230 glyphsToCharactersBuffer + endGlyphIndexPlusOne);
232 // Clear the characters per glyph buffer.
233 Length* charactersPerGlyphBuffer = model->mVisualModel->mCharactersPerGlyph.Begin();
234 model->mVisualModel->mCharactersPerGlyph.Erase(charactersPerGlyphBuffer + textUpdateInfo.mStartGlyphIndex,
235 charactersPerGlyphBuffer + endGlyphIndexPlusOne);
237 // Should pass if mGlyphPositions has already been cleared in Controller::Relayouter::Relayout
238 if(0u != model->mVisualModel->mGlyphPositions.Count())
240 // Clear the positions buffer.
241 Vector2* positionsBuffer = model->mVisualModel->mGlyphPositions.Begin();
242 model->mVisualModel->mGlyphPositions.Erase(positionsBuffer + textUpdateInfo.mStartGlyphIndex,
243 positionsBuffer + endGlyphIndexPlusOne);
247 if(Controller::NO_OPERATION != (Controller::LAYOUT & operations))
250 uint32_t startRemoveIndex = model->mVisualModel->mLines.Count();
251 uint32_t endRemoveIndex = startRemoveIndex;
252 ClearCharacterRuns(startIndex,
254 model->mVisualModel->mLines,
258 // Will update the glyph runs.
259 startRemoveIndex = model->mVisualModel->mLines.Count();
260 endRemoveIndex = startRemoveIndex;
261 ClearGlyphRuns(textUpdateInfo.mStartGlyphIndex,
262 endGlyphIndexPlusOne - 1u,
263 model->mVisualModel->mLines,
267 // Set the line index from where to insert the new laid-out lines.
268 textUpdateInfo.mStartLineIndex = startRemoveIndex;
270 LineRun* linesBuffer = model->mVisualModel->mLines.Begin();
271 model->mVisualModel->mLines.Erase(linesBuffer + startRemoveIndex,
272 linesBuffer + endRemoveIndex);
275 if(Controller::NO_OPERATION != (Controller::COLOR & operations))
277 if(0u != model->mVisualModel->mColorIndices.Count())
279 ColorIndex* colorIndexBuffer = model->mVisualModel->mColorIndices.Begin();
280 model->mVisualModel->mColorIndices.Erase(colorIndexBuffer + textUpdateInfo.mStartGlyphIndex,
281 colorIndexBuffer + endGlyphIndexPlusOne);
284 if(0u != model->mVisualModel->mBackgroundColorIndices.Count())
286 ColorIndex* backgroundColorIndexBuffer = model->mVisualModel->mBackgroundColorIndices.Begin();
287 model->mVisualModel->mBackgroundColorIndices.Erase(backgroundColorIndexBuffer + textUpdateInfo.mStartGlyphIndex,
288 backgroundColorIndexBuffer + endGlyphIndexPlusOne);
293 void ControllerImplDataClearer::ClearModelData(Controller::Impl& impl, CharacterIndex startIndex, CharacterIndex endIndex, Controller::OperationsMask operations)
295 TextUpdateInfo& textUpdateInfo = impl.mTextUpdateInfo;
297 if(textUpdateInfo.mClearAll ||
298 ((0u == startIndex) &&
299 (textUpdateInfo.mPreviousNumberOfCharacters == endIndex + 1u)))
301 ClearFullModelData(impl, operations);
305 // Clear the model data related with characters.
306 ClearCharacterModelData(impl, startIndex, endIndex, operations);
308 // Clear the model data related with glyphs.
309 ClearGlyphModelData(impl, startIndex, endIndex, operations);
312 ModelPtr& model = impl.mModel;
314 // The estimated number of lines. Used to avoid reallocations when layouting.
315 textUpdateInfo.mEstimatedNumberOfLines = std::max(model->mVisualModel->mLines.Count(), model->mLogicalModel->mParagraphInfo.Count());
317 model->mVisualModel->ClearCaches();
320 } // namespace Dali::Toolkit::Text