TextModel - Create paragraph info for a given range of characters inside a text.
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit-internal / utc-Dali-Text-Segmentation.cpp
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 #include <iostream>
19
20 #include <stdlib.h>
21 #include <dali-toolkit/internal/text/character-set-conversion.h>
22 #include <dali-toolkit/internal/text/segmentation.h>
23 #include <dali-toolkit-test-suite-utils.h>
24 #include <dali-toolkit/dali-toolkit.h>
25
26
27 using namespace Dali;
28 using namespace Toolkit;
29 using namespace Text;
30
31 // Tests the following functions with different scripts.
32 // void SetLineBreakInfo( const Vector<Character>& text,
33 //                        Vector<LineBreakInfo>& lineBreakInfo );
34 // void SetWordBreakInfo( const Vector<Character>& text,
35 //                        CharacterIndex startIndex,
36 //                        Length numberOfCharacters,
37 //                        Vector<WordBreakInfo>& wordBreakInfo );
38
39 //////////////////////////////////////////////////////////
40
41 namespace
42 {
43
44 struct BreakInfoData
45 {
46   std::string description;        ///< Description of the test.
47   std::string text;               ///< input text.
48   uint32_t    index;              ///< The index from where to start to query the break info.
49   uint32_t    numberOfCharacters; ///< The requested number of characters.
50   std::string breakInfo;          ///< The expected break info.
51 };
52
53 bool LineBreakInfoTest( const BreakInfoData& data )
54 {
55   // 1) Convert to utf32
56   Vector<Character> utf32;
57   utf32.Resize( data.text.size() );
58
59   const uint32_t numberOfCharacters = Utf8ToUtf32( reinterpret_cast<const uint8_t* const>( data.text.c_str() ),
60                                                    data.text.size(),
61                                                    &utf32[0u] );
62
63   utf32.Resize( numberOfCharacters );
64
65   // 2) Set the line break info for the whole text.
66   Vector<LineBreakInfo> lineBreakInfo;
67   lineBreakInfo.Resize( numberOfCharacters );
68
69   SetLineBreakInfo( utf32,
70                     0u,
71                     numberOfCharacters,
72                     lineBreakInfo );
73
74   // 3) Update the word text info if it's requested for part of the text.
75   if( ( 0u != data.index ) &&
76       ( numberOfCharacters != data.numberOfCharacters ) )
77   {
78     // Clear part of the line break info.
79     lineBreakInfo.Erase( lineBreakInfo.Begin() + data.index,
80                          lineBreakInfo.Begin() + data.index + data.numberOfCharacters );
81
82     // Update the word line info.
83     SetLineBreakInfo( utf32,
84                       data.index,
85                       data.numberOfCharacters,
86                       lineBreakInfo );
87   }
88
89   // 4) compare the results
90   std::ostringstream breakInfo;
91
92   for( unsigned int index = 0u; index < numberOfCharacters; ++index )
93   {
94     breakInfo << static_cast<unsigned int>( lineBreakInfo[index] );
95   }
96
97   if( data.breakInfo != breakInfo.str() )
98   {
99     std::cout << "                text : [" << data.text << "]" << std::endl;
100     std::cout << "               index : " <<  data.index << std::endl;
101     std::cout << "  numberOfCharacters : " <<  data.numberOfCharacters << std::endl;
102     std::cout << "            expected : [" << data.breakInfo << "]" << std::endl;
103     std::cout << "                 got : [" << breakInfo.str() << "]" << std::endl;
104     return false;
105   }
106
107   return true;
108 }
109
110 bool WordBreakInfoTest( const BreakInfoData& data )
111 {
112   // 1) Convert to utf32
113   Vector<Character> utf32;
114   utf32.Resize( data.text.size() );
115
116   const uint32_t numberOfCharacters = Utf8ToUtf32( reinterpret_cast<const uint8_t* const>( data.text.c_str() ),
117                                                    data.text.size(),
118                                                    &utf32[0u] );
119
120   utf32.Resize( numberOfCharacters );
121
122   // 2) Set the word break info for the whole text.
123   Vector<WordBreakInfo> wordBreakInfo;
124   wordBreakInfo.Resize( numberOfCharacters );
125
126   SetWordBreakInfo( utf32,
127                     0u,
128                     numberOfCharacters,
129                     wordBreakInfo );
130
131   // 3) Update the word text info if it's requested for part of the text.
132   if( ( 0u != data.index ) &&
133       ( numberOfCharacters != data.numberOfCharacters ) )
134   {
135     // Clear part of the word break info.
136     wordBreakInfo.Erase( wordBreakInfo.Begin() + data.index,
137                          wordBreakInfo.Begin() + data.index + data.numberOfCharacters );
138
139     // Update the word break info.
140     SetWordBreakInfo( utf32,
141                       data.index,
142                       data.numberOfCharacters,
143                       wordBreakInfo );
144   }
145
146   // 4) compare the results
147   std::ostringstream breakInfo;
148
149   for( unsigned int index = 0u; index < numberOfCharacters; ++index )
150   {
151     breakInfo << static_cast<unsigned int>( wordBreakInfo[index] );
152   }
153
154   if( data.breakInfo != breakInfo.str() )
155   {
156     std::cout << "                text : [" << data.text << "]" << std::endl;
157     std::cout << "               index : " <<  data.index << std::endl;
158     std::cout << "  numberOfCharacters : " <<  data.numberOfCharacters << std::endl;
159     std::cout << "            expected : [" << data.breakInfo << "]" << std::endl;
160     std::cout << "                 got : [" << breakInfo.str() << "]" << std::endl;
161     return false;
162   }
163
164   return true;
165 }
166
167 } // namespace
168
169 //////////////////////////////////////////////////////////
170
171 int UtcDaliTextSegnemtationSetLineBreakInfo(void)
172 {
173   tet_infoline(" UtcDaliTextSegnemtationSetLineBreakInfo");
174
175   struct BreakInfoData data[] =
176   {
177     {
178       "Zero characters",
179       "",
180       0u,
181       0u,
182       "",
183     },
184     {
185       "Latin script",
186       "Lorem ipsum dolor sit amet, aeque definiebas ea mei, posse iracundia ne cum.\n"
187       "Usu ne nisl maiorum iudicabit, veniam epicurei oporteat eos an.\n"
188       "Ne nec nulla regione albucius, mea doctus delenit ad!\n"
189       "Et everti blandit adversarium mei, eam porro neglegentur suscipiantur an.\n"
190       "Quidam corpora at duo. An eos possim scripserit?",
191       0u,
192       317u,
193       "22222122222122222122212222212222212222222222122122221222221222222222122122220"
194       "2221221222212222222122222222221222222122222222122222222122212220"
195       "221222122222122222221222222222122212222221222222212220"
196       "22122222212222222122222222222122221222122222122222222222122222222222212220"
197       "222222122222221221222212212221222222122222222220",
198     },
199     {
200       "Latin script. Update initial paragraphs.",
201       "Lorem ipsum dolor sit amet, aeque definiebas ea mei, posse iracundia ne cum.\n"
202       "Usu ne nisl maiorum iudicabit, veniam epicurei oporteat eos an.\n"
203       "Ne nec nulla regione albucius, mea doctus delenit ad!\n"
204       "Et everti blandit adversarium mei, eam porro neglegentur suscipiantur an.\n"
205       "Quidam corpora at duo. An eos possim scripserit?",
206       0u,
207       141u,
208       "22222122222122222122212222212222212222222222122122221222221222222222122122220"
209       "2221221222212222222122222222221222222122222222122222222122212220"
210       "221222122222122222221222222222122212222221222222212220"
211       "22122222212222222122222222222122221222122222122222222222122222222222212220"
212       "222222122222221221222212212221222222122222222220",
213     },
214     {
215       "Latin script. Update mid paragraphs.",
216       "Lorem ipsum dolor sit amet, aeque definiebas ea mei, posse iracundia ne cum.\n"
217       "Usu ne nisl maiorum iudicabit, veniam epicurei oporteat eos an.\n"
218       "Ne nec nulla regione albucius, mea doctus delenit ad!\n"
219       "Et everti blandit adversarium mei, eam porro neglegentur suscipiantur an.\n"
220       "Quidam corpora at duo. An eos possim scripserit?",
221       141u,
222       128u,
223       "22222122222122222122212222212222212222222222122122221222221222222222122122220"
224       "2221221222212222222122222222221222222122222222122222222122212220"
225       "221222122222122222221222222222122212222221222222212220"
226       "22122222212222222122222222222122221222122222122222222222122222222222212220"
227       "222222122222221221222212212221222222122222222220",
228     },
229     {
230       "Latin script. Update final paragraphs.",
231       "Lorem ipsum dolor sit amet, aeque definiebas ea mei, posse iracundia ne cum.\n"
232       "Usu ne nisl maiorum iudicabit, veniam epicurei oporteat eos an.\n"
233       "Ne nec nulla regione albucius, mea doctus delenit ad!\n"
234       "Et everti blandit adversarium mei, eam porro neglegentur suscipiantur an.\n"
235       "Quidam corpora at duo. An eos possim scripserit?",
236       195u,
237       122u,
238       "22222122222122222122212222212222212222222222122122221222221222222222122122220"
239       "2221221222212222222122222222221222222122222222122222222122212220"
240       "221222122222122222221222222222122212222221222222212220"
241       "22122222212222222122222222222122221222122222122222222222122222222222212220"
242       "222222122222221221222212212221222222122222222220",
243     },
244     {
245       "Japanese script",
246       "韓国側は北朝鮮当局を通じて米ドルで賃金を支払う。\n"
247       "国際社会から様々な経済制裁を受ける北朝鮮にとっては出稼ぎ労働などと並んで重要な外貨稼ぎの手段となっている。\n"
248       "韓国統一省によると15年だけで1320億ウォン(約130億円)が同工業団地を通じ北朝鮮に支払われたという。",
249       0u,
250       132u,
251       "1111111111111111111111220"
252       "111111211111111111111111111111111111111111111111111220"
253       "11111111121111122211111212211211111111111111111111120",
254     },
255     {
256       "Chinese script",
257       "在被捕的64人中,警方落案起訴了35名男子和3名女子,他們年齡介乎15到70歲。\n"
258       "38人中有1人獲准保釋。\n"
259       "16名年齡介乎14到33歲的被捕人士獲准保釋候查,另有10人仍被拘留作進一步調查。",
260       0u,
261       95u,
262       "11112112111111112111111112111111121121220"
263       "2111111111220"
264       "21111112112111111111111211121111111111120",
265     }
266   };
267   const unsigned int numberOfTests = 7u;
268
269   for( unsigned int index = 0u; index < numberOfTests; ++index )
270   {
271     ToolkitTestApplication application;
272     if( !LineBreakInfoTest( data[index] ) )
273     {
274       tet_result(TET_FAIL);
275     }
276   }
277
278   tet_result(TET_PASS);
279   END_TEST;
280 }
281
282 int UtcDaliTextSegnemtationSetWordBreakInfo(void)
283 {
284   tet_infoline(" UtcDaliTextSegnemtationSetWordBreakInfo");
285
286   struct BreakInfoData data[] =
287   {
288     {
289       "Zero characters.",
290       "",
291       0u,
292       0u,
293       "",
294     },
295     {
296       "Latin script, full text.",
297       "Lorem ipsum dolor sit amet, aeque definiebas ea mei, posse iracundia ne cum.\n"
298       "Usu ne nisl maiorum iudicabit, veniam epicurei oporteat eos an.\n"
299       "Ne nec nulla regione albucius, mea doctus delenit ad!\n"
300       "Et everti blandit adversarium mei, eam porro neglegentur suscipiantur an.\n"
301       "Quidam corpora at duo. An eos possim scripserit?",
302       0u,
303       317u,
304       "11110011110011110011001110001111001111111110010011000111100111111110010011000"
305       "1100100111001111110011111111000111110011111110011111110011001000"
306       "100110011110011111100111111100011001111100111111001000"
307       "10011111001111110011111111110011000110011110011111111110011111111111001000"
308       "111110011111100100110001001100111110011111111100",
309     },
310     {
311       "Latin script, update first paragraph.",
312       "Lorem ipsum dolor sit amet, aeque definiebas ea mei, posse iracundia ne cum.\n"
313       "Usu ne nisl maiorum iudicabit, veniam epicurei oporteat eos an.\n"
314       "Ne nec nulla regione albucius, mea doctus delenit ad!\n"
315       "Et everti blandit adversarium mei, eam porro neglegentur suscipiantur an.\n"
316       "Quidam corpora at duo. An eos possim scripserit?",
317       0u,
318       77u,
319       "11110011110011110011001110001111001111111110010011000111100111111110010011000"
320       "1100100111001111110011111111000111110011111110011111110011001000"
321       "100110011110011111100111111100011001111100111111001000"
322       "10011111001111110011111111110011000110011110011111111110011111111111001000"
323       "111110011111100100110001001100111110011111111100",
324     },
325     {
326       "Latin script, update middle paragraphs.",
327       "Lorem ipsum dolor sit amet, aeque definiebas ea mei, posse iracundia ne cum.\n"
328       "Usu ne nisl maiorum iudicabit, veniam epicurei oporteat eos an.\n"
329       "Ne nec nulla regione albucius, mea doctus delenit ad!\n"
330       "Et everti blandit adversarium mei, eam porro neglegentur suscipiantur an.\n"
331       "Quidam corpora at duo. An eos possim scripserit?",
332       77u,
333       118u,
334       "11110011110011110011001110001111001111111110010011000111100111111110010011000"
335       "1100100111001111110011111111000111110011111110011111110011001000"
336       "100110011110011111100111111100011001111100111111001000"
337       "10011111001111110011111111110011000110011110011111111110011111111111001000"
338       "111110011111100100110001001100111110011111111100",
339     },
340     {
341       "Latin script, update last paragraph.",
342       "Lorem ipsum dolor sit amet, aeque definiebas ea mei, posse iracundia ne cum.\n"
343       "Usu ne nisl maiorum iudicabit, veniam epicurei oporteat eos an.\n"
344       "Ne nec nulla regione albucius, mea doctus delenit ad!\n"
345       "Et everti blandit adversarium mei, eam porro neglegentur suscipiantur an.\n"
346       "Quidam corpora at duo. An eos possim scripserit?",
347       269u,
348       48u,
349       "11110011110011110011001110001111001111111110010011000111100111111110010011000"
350       "1100100111001111110011111111000111110011111110011111110011001000"
351       "100110011110011111100111111100011001111100111111001000"
352       "10011111001111110011111111110011000110011110011111111110011111111111001000"
353       "111110011111100100110001001100111110011111111100",
354     },
355     {
356       "Japanese script, full text.",
357       "韓国側は北朝鮮当局を通じて米ドルで賃金を支払う。\n"
358       "国際社会から様々な経済制裁を受ける北朝鮮にとっては出稼ぎ労働などと並んで重要な外貨稼ぎの手段となっている。\n"
359       "韓国統一省によると15年だけで1320億ウォン(約130億円)が同工業団地を通じ北朝鮮に支払われたという。",
360       0u,
361       132u,
362       "0000000000000010000000000"
363       "000000000000000000000000000000000000000000000000000000"
364       "00000000010000011100110001100000000000000000000000000",
365     },
366     {
367       "Japanese script, update first paragraph.",
368       "韓国側は北朝鮮当局を通じて米ドルで賃金を支払う。\n"
369       "国際社会から様々な経済制裁を受ける北朝鮮にとっては出稼ぎ労働などと並んで重要な外貨稼ぎの手段となっている。\n"
370       "韓国統一省によると15年だけで1320億ウォン(約130億円)が同工業団地を通じ北朝鮮に支払われたという。",
371       0u,
372       25u,
373       "0000000000000010000000000"
374       "000000000000000000000000000000000000000000000000000000"
375       "00000000010000011100110001100000000000000000000000000",
376     },
377     {
378       "Japanese script, update middle paragraph.",
379       "韓国側は北朝鮮当局を通じて米ドルで賃金を支払う。\n"
380       "国際社会から様々な経済制裁を受ける北朝鮮にとっては出稼ぎ労働などと並んで重要な外貨稼ぎの手段となっている。\n"
381       "韓国統一省によると15年だけで1320億ウォン(約130億円)が同工業団地を通じ北朝鮮に支払われたという。",
382       25u,
383       54u,
384       "0000000000000010000000000"
385       "000000000000000000000000000000000000000000000000000000"
386       "00000000010000011100110001100000000000000000000000000",
387     },
388     {
389       "Japanese script, update last paragraph.",
390       "韓国側は北朝鮮当局を通じて米ドルで賃金を支払う。\n"
391       "国際社会から様々な経済制裁を受ける北朝鮮にとっては出稼ぎ労働などと並んで重要な外貨稼ぎの手段となっている。\n"
392       "韓国統一省によると15年だけで1320億ウォン(約130億円)が同工業団地を通じ北朝鮮に支払われたという。",
393       79u,
394       53u,
395       "0000000000000010000000000"
396       "000000000000000000000000000000000000000000000000000000"
397       "00000000010000011100110001100000000000000000000000000",
398     },
399     {
400       "Chinese script, full text.",
401       "在被捕的64人中,警方落案起訴了35名男子和3名女子,他們年齡介乎15到70歲。\n"
402       "38人中有1人獲准保釋。\n"
403       "16名年齡介乎14到33歲的被捕人士獲准保釋候查,另有10人仍被拘留作進一步調查。",
404       0u,
405       95u,
406       "00001000000000001000000000000000010010000"
407       "1000000000000"
408       "10000001001000000000000000010000000000000",
409     },
410     {
411       "Chinese script, update first paragraph.",
412       "在被捕的64人中,警方落案起訴了35名男子和3名女子,他們年齡介乎15到70歲。\n"
413       "38人中有1人獲准保釋。\n"
414       "16名年齡介乎14到33歲的被捕人士獲准保釋候查,另有10人仍被拘留作進一步調查。",
415       0u,
416       41u,
417       "00001000000000001000000000000000010010000"
418       "1000000000000"
419       "10000001001000000000000000010000000000000",
420     },
421     {
422       "Chinese script, update middle paragraph.",
423       "在被捕的64人中,警方落案起訴了35名男子和3名女子,他們年齡介乎15到70歲。\n"
424       "38人中有1人獲准保釋。\n"
425       "16名年齡介乎14到33歲的被捕人士獲准保釋候查,另有10人仍被拘留作進一步調查。",
426       41u,
427       13u,
428       "00001000000000001000000000000000010010000"
429       "1000000000000"
430       "10000001001000000000000000010000000000000",
431     },
432     {
433       "Chinese script, update last paragraph.",
434       "在被捕的64人中,警方落案起訴了35名男子和3名女子,他們年齡介乎15到70歲。\n"
435       "38人中有1人獲准保釋。\n"
436       "16名年齡介乎14到33歲的被捕人士獲准保釋候查,另有10人仍被拘留作進一步調查。",
437       54u,
438       41u,
439       "00001000000000001000000000000000010010000"
440       "1000000000000"
441       "10000001001000000000000000010000000000000",
442     }
443   };
444   const unsigned int numberOfTests = 13u;
445
446   for( unsigned int index = 0u; index < numberOfTests; ++index )
447   {
448     ToolkitTestApplication application;
449     if( !WordBreakInfoTest( data[index] ) )
450     {
451       tet_result(TET_FAIL);
452     }
453   }
454
455   tet_result(TET_PASS);
456   END_TEST;
457 }