2 * Copyright (c) 2015 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/public-api/text/logical-model.h>
22 #include <dali-toolkit/public-api/text/font-run.h>
23 #include <dali-toolkit/public-api/text/script-run.h>
38 struct LogicalModel::Impl
40 Vector<Character> mText;
41 Vector<ScriptRun> mScriptRuns;
42 Vector<FontRun> mFontRuns;
45 LogicalModelPtr LogicalModel::New()
47 return LogicalModelPtr( new LogicalModel() );
50 void LogicalModel::SetText( const Character* text, Length length )
52 Vector<Character>& modelText = mImpl->mText;
53 modelText.Resize( length );
54 memcpy( &modelText[0], text, length*sizeof(Character) );
57 Length LogicalModel::GetNumberOfCharacters() const
59 return mImpl->mText.Count();
62 void LogicalModel::GetText( CharacterIndex characterIndex, Character* text, Length numberOfCharacters ) const
64 Vector<Character>& modelText = mImpl->mText;
65 memcpy( text, &modelText[characterIndex], numberOfCharacters*sizeof(Character) );
68 void LogicalModel::SetScripts( const ScriptRun* const scripts,
71 Vector<ScriptRun>& scriptRuns = mImpl->mScriptRuns;
72 scriptRuns.Resize( numberOfRuns );
73 memcpy( scriptRuns.Begin(), scripts, numberOfRuns * sizeof( ScriptRun ) );
76 Length LogicalModel::GetNumberOfScriptRuns( CharacterIndex characterIndex,
77 Length numberOfCharacters ) const
79 if( ( 0u == characterIndex ) && ( mImpl->mText.Count() == numberOfCharacters ) )
81 return mImpl->mScriptRuns.Count();
84 const CharacterIndex charcterEndIndex = characterIndex + numberOfCharacters;
85 Length numberOfScriptRuns = 0u;
86 bool firstIndexFound = false;
88 for( Length index = 0u, length = mImpl->mScriptRuns.Count(); index < length; ++index )
90 const ScriptRun* const scriptRun = mImpl->mScriptRuns.Begin() + index;
92 if( !firstIndexFound &&
93 ( characterIndex < scriptRun->characterRun.characterIndex + scriptRun->characterRun.numberOfCharacters ) )
95 // The character index is within this script run.
96 // Starts the counter of script runs.
97 firstIndexFound = true;
100 if( firstIndexFound )
102 ++numberOfScriptRuns;
103 if( scriptRun->characterRun.characterIndex + scriptRun->characterRun.numberOfCharacters > charcterEndIndex )
105 // This script run exceeds the given range. The number of scripts can be returned.
106 return numberOfScriptRuns;
111 return numberOfScriptRuns;
114 void LogicalModel::GetScriptRuns( ScriptRun* scriptRuns,
115 CharacterIndex characterIndex,
116 Length numberOfCharacters ) const
118 // A better implementation can cache the first script run and the number of then when the GetNumberOfScriptRuns() is called.
120 Length numberOfScriptRuns = GetNumberOfScriptRuns( characterIndex,
121 numberOfCharacters );
123 for( Length index = 0u, length = mImpl->mScriptRuns.Count(); index < length; ++index )
125 const ScriptRun* const scriptRun = mImpl->mScriptRuns.Begin() + index;
127 if( characterIndex < scriptRun->characterRun.characterIndex + scriptRun->characterRun.numberOfCharacters )
129 memcpy( scriptRuns, scriptRun, sizeof( ScriptRun ) * numberOfScriptRuns );
135 Script LogicalModel::GetScript( CharacterIndex characterIndex ) const
137 // If this operation is too slow, consider a binary search.
139 for( Length index = 0u, length = mImpl->mScriptRuns.Count(); index < length; ++index )
141 const ScriptRun* const scriptRun = mImpl->mScriptRuns.Begin() + index;
143 if( ( scriptRun->characterRun.characterIndex <= characterIndex ) &&
144 ( characterIndex < scriptRun->characterRun.characterIndex + scriptRun->characterRun.numberOfCharacters ) )
146 return scriptRun->script;
150 return TextAbstraction::UNKNOWN;
153 void LogicalModel::SetFonts( const FontRun* const fonts,
154 Length numberOfRuns )
156 Vector<FontRun>& fontRuns = mImpl->mFontRuns;
157 fontRuns.Resize( numberOfRuns );
158 memcpy( fontRuns.Begin(), fonts, numberOfRuns * sizeof( FontRun ) );
161 Length LogicalModel::GetNumberOfFontRuns( CharacterIndex characterIndex,
162 Length numberOfCharacters ) const
164 if( ( 0u == characterIndex ) && ( mImpl->mText.Count() == numberOfCharacters ) )
166 return mImpl->mFontRuns.Count();
169 const CharacterIndex charcterEndIndex = characterIndex + numberOfCharacters;
170 Length numberOfFontRuns = 0u;
171 bool firstIndexFound = false;
173 for( Length index = 0u, length = mImpl->mFontRuns.Count(); index < length; ++index )
175 const FontRun* const fontRun = mImpl->mFontRuns.Begin() + index;
177 if( !firstIndexFound &&
178 ( characterIndex < fontRun->characterRun.characterIndex + fontRun->characterRun.numberOfCharacters ) )
180 // The character index is within this font run.
181 // Starts the counter of font runs.
182 firstIndexFound = true;
185 if( firstIndexFound )
188 if( fontRun->characterRun.characterIndex + fontRun->characterRun.numberOfCharacters > charcterEndIndex )
190 // This font run exceeds the given range. The number of fonts can be returned.
191 return numberOfFontRuns;
196 return numberOfFontRuns;
199 void LogicalModel::GetFontRuns( FontRun* fontRuns,
200 CharacterIndex characterIndex,
201 Length numberOfCharacters ) const
203 // A better implementation can cache the first font run and the number of then when the GetNumberOfFontRuns() is called.
205 Length numberOfFontRuns = GetNumberOfFontRuns( characterIndex,
206 numberOfCharacters );
208 for( Length index = 0u, length = mImpl->mFontRuns.Count(); index < length; ++index )
210 const FontRun* const fontRun = mImpl->mFontRuns.Begin() + index;
212 if( characterIndex < fontRun->characterRun.characterIndex + fontRun->characterRun.numberOfCharacters )
214 memcpy( fontRuns, fontRun, sizeof( FontRun ) * numberOfFontRuns );
220 FontId LogicalModel::GetFont( CharacterIndex characterIndex ) const
222 for( Length index = 0u, length = mImpl->mFontRuns.Count(); index < length; ++index )
224 const FontRun* const fontRun = mImpl->mFontRuns.Begin() + index;
226 if( ( fontRun->characterRun.characterIndex <= characterIndex ) &&
227 ( characterIndex < fontRun->characterRun.characterIndex + fontRun->characterRun.numberOfCharacters ) )
229 return fontRun->fontId;
236 void LogicalModel::SetLineBreakInfo( const LineBreakInfo* const lineBreakInfo,
241 void LogicalModel::GetLineBreakInfo( LineBreakInfo* lineBreakInfo,
242 CharacterIndex characterIndex,
243 Length numberOfItems ) const
247 LineBreakInfo LogicalModel::GetLineBreakInfo( CharacterIndex characterIndex ) const
252 void LogicalModel::SetWordBreakInfo( const WordBreakInfo* const wordBreakInfo,
257 void LogicalModel::GetWordBreakInfo( WordBreakInfo* wordBreakInfo,
258 CharacterIndex characterIndex,
259 Length numberOfItems ) const
263 WordBreakInfo LogicalModel::GetWordBreakInfo( CharacterIndex characterIndex ) const
268 void LogicalModel::SetBidirectionalInfo( const BidirectionalParagraphInfoRun* const bidirectionalInfo,
269 Length numberOfRuns )
273 Length LogicalModel::GetNumberOfBidirectionalInfoRuns( CharacterIndex characterIndex,
274 Length numberOfCharacters ) const
279 void LogicalModel::GetCharacterDirections( CharacterDirection* directions,
280 CharacterIndex characterIndex,
281 Length numberOfCharacters ) const
285 CharacterDirection LogicalModel::GetCharacterDirection( CharacterIndex characterIndex ) const
290 void LogicalModel::SetVisualToLogicalMap( const BidirectionalLineInfoRun* const bidirectionalInfo,
291 Length numberOfRuns )
295 CharacterIndex LogicalModel::GetVisualCharacterIndex( CharacterIndex logicalCharacterIndex ) const
300 CharacterIndex LogicalModel::GetLogicalCharacterIndex( CharacterIndex visualCharacterIndex ) const
305 void LogicalModel::GetLogicalToVisualMap( CharacterIndex* logicalToVisualMap,
306 CharacterIndex characterIndex,
307 Length numberOfCharacters ) const
311 void LogicalModel::GetVisualToLogicalMap( CharacterIndex* visualToLogicalMap,
312 CharacterIndex characterIndex,
313 Length numberOfCharacters ) const
317 LogicalModel::~LogicalModel()
322 LogicalModel::LogicalModel()
325 mImpl = new LogicalModel::Impl();
330 } // namespace Toolkit