Add the 'Carriage Return' character to the IsNewParagraph().
[platform/core/uifw/dali-adaptor.git] / text / dali / devel-api / text-abstraction / script.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 // FILE HEADER
19 #include <dali/devel-api/text-abstraction/script.h>
20
21 namespace Dali
22 {
23
24 namespace TextAbstraction
25 {
26
27 namespace
28 {
29 const unsigned int WHITE_SPACE_THRESHOLD  = 0x21; ///< All characters below 0x21 are considered white spaces.
30 const unsigned int CHAR_LF   = 0x000A; ///< NL Line feed, new line.
31 const unsigned int CHAR_VT   = 0x000B; ///< Vertical tab.
32 const unsigned int CHAR_FF   = 0x000C; ///< NP Form feed, new page.
33 const unsigned int CHAR_CR   = 0x000D; ///< Carriage return, new line.
34 const unsigned int CHAR_NEL  = 0x0085; ///< Next line.
35 const unsigned int CHAR_LS   = 0x2028; ///< Line separator.
36 const unsigned int CHAR_PS   = 0x2029; ///< Paragraph separator
37
38 const unsigned int CHAR_ZWS  = 0x200B; ///< Zero width space.
39 const unsigned int CHAR_ZWNJ = 0x200C; ///< Zero width non joiner.
40 const unsigned int CHAR_ZWJ  = 0x200D; ///< Zero width joiner.
41 const unsigned int CHAR_LTRM = 0x200E; ///< Left to Right Mark.
42 const unsigned int CHAR_RTLM = 0x200F; ///< Right to Left Mark.
43 const unsigned int CHAR_TS   = 0x2009; ///< Thin Space.
44 } // namespace
45
46 bool IsRightToLeftScript( Script script )
47 {
48   return ( ( ARABIC == script ) ||
49            ( HEBREW == script ) );
50 }
51
52 Script GetCharacterScript( Character character )
53 {
54   // Latin script:
55   // 0x0000 - 0x007f C0 Controls and Basic Latin
56   // 0x0080 - 0x00ff C1 Controls and Latin-1 Supplement
57   // 0x0100 - 0x017f Latin Extended-A
58   // 0x0180 - 0x024f Latin Extended-B
59   // 0x0250 - 0x02af IPA Extensions
60   // 0x02b0 - 0x02ff Spacing Modifier Letters
61   // 0x1d00 - 0x1d7f Phonetic Extensions
62   // 0x1d80 - 0x1dbf Phonetic Extensions Supplement
63   // 0x1e00 - 0x1eff Latin Extended Additional
64   // 0x2070 - 0x209f Superscripts and Subscripts
65   // 0x2100 - 0x214f Letterlike symbols
66   // 0x2150 - 0x218f Number Forms
67   // 0x2c60 - 0x2c7f Latin Extended-C
68   // 0xa720 - 0xa7ff Latin Extended-D
69   // 0xab30 - 0xab6f Latin Extended-E
70   // 0xfb00 - 0xfb06 Latin Alphabetic Presentation Forms
71   // 0xff00 - 0xffef Halfwidth and Fullwidth Forms
72
73   // Brahmic scripts:
74   // 0x0900 - 0x097f Devanagari
75   // 0x0980 - 0x09ff Bengali
76   // 0x0a00 - 0x0a7f Gurmukhi
77   // 0x0a80 - 0x0aff Gujarati
78   // 0x0b00 - 0x0b7f Oriya
79   // 0x0b80 - 0x0bff Tamil
80   // 0x0c00 - 0x0c7f Telugu
81   // 0x0c80 - 0x0cff Kannada
82   // 0x0d00 - 0x0d7f Malayalam
83
84   // Sinhala script.
85   // 0x0d80 - 0x0dff Sinhala
86
87   // Arabic script.
88   // 0x0600 - 0x06ff Arabic
89   // 0x0750 - 0x077f Arabic Supplement
90   // 0x08A0 - 0x08ff Arabic Extended-A
91   // 0xfb50 - 0xfdff Arabic Presentation Forms-A
92   // 0xfe70 - 0xfeff Arabic Presentation Forms-B
93   // 0x1ee00 - 0x1eeff Arabic Mathematical Alphabetic Symbols
94
95   // CJK (Chinese, Japanese and Korean) and Vietnamese script.
96   // 0x2e80 - 0x2eff CJK Radicals Supplement
97   // 0x2f00 - 0x2fdf Kangxi Radicals
98   // 0x3000 - 0x303f CJK Symbols and Punctuation
99   // 0x3200 - 0x32ff Enclosed CJK Letters and Months
100   // 0x3400 - 0x4dbf CJK Unified Ideographs Extension A
101   // 0x4e00 - 0x62ff CJK Unified Ideographs
102   // 0x6300 - 0x77ff CJK Unified Ideographs
103   // 0x7800 - 0x8cff CJK Unified Ideographs
104   // 0x8d00 - 0x9fff CJK Unified Ideographs
105   // 0x20000 - 0x215ff CJK Unified Ideographs Extension B
106   // 0x21600 - 0x230ff CJK Unified Ideographs Extension B
107   // 0x23100 - 0x245ff CJK Unified Ideographs Extension B
108   // 0x24600 - 0x260ff CJK Unified Ideographs Extension B
109   // 0x26100 - 0x275ff CJK Unified Ideographs Extension B
110   // 0x27600 - 0x290ff CJK Unified Ideographs Extension B
111   // 0x29100 - 0x2a6df CJK Unified Ideographs Extension B
112   // 0x2a700 - 0x2b73f CJK Unified Ideographs Extension C
113   // 0x2b740 - 0x2b81f CJK Unified Ideographs Extension D
114
115   // Japanese scripts.
116   // 0x3040 - 0x309f Hiragana
117   // 0x30a0 - 0x30ff Katakana
118
119   // Hangul script
120   // 0x1100 - 0x11ff Hangul jamo
121   // 0x3130 - 0x318f Hangul Compatibility Jamo
122   // 0xa960 - 0xa97f Hangul Jamo Extended-A
123   // 0xac00 - 0xd7af Hangul Syllables
124   // 0xd7b0 - 0xd7ff Hangul Jamo Extended-B
125
126   // Khmer script
127   // 0x1780 - 0x17ff Khmer
128   // 0x19e0 - 0x19ff Khmer Symbols
129
130   // Lao script
131   // 0x0e80 - 0x0eff Lao
132
133   // Thai script
134   // 0x0e00 - 0x0e7f Thai
135
136   // Burmese script
137   // 0x1000 - 0x109f Myanmar
138
139   // Hebrew script
140   // 0x0591 - 0x05f4 Hebrew
141   // 0xfb1d - 0xfb4f Hebrew subset of Alphabetic Presentation Forms
142
143   // Cyrillic script
144   // 0x0400 - 0x04ff Cyrillic
145   // 0x0500 - 0x052f Cyrillic suplement
146   // 0x2de0 - 0x2dff Cyrillic Extended-A
147   // 0xa640 - 0xa69f Cyrillic Extended-B
148
149   // Georgian script
150   // 0x10a0 - 0x10ff Georgian
151   // 0x2d00 - 0x2d2f Georgian suplement
152
153   // Greek script
154   // 0x0370 - 0x03ff Greek & Coptic
155   // 0x1f00 - 0x1fff Greek Extended
156
157   // Armenian script
158   // 0x0530 - 0x058f Armenian
159   // 0xfb13 - 0xfb17 Armenian subset of Alphabetic prefentation forms
160
161   // The Emoji which map to standardized Unicode characters
162   // 1. Emoticons ( 1F601 - 1F64F )
163   // 2. Dingbats ( 2702 - 27B0 )
164   // 3. Transport and map symbols ( 1F680 - 1F6C0 )
165   // 4. Enclosed characters ( 24C2 - 1F251 )
166   // 5. Uncategorized :-S
167   // 6. Additional Emoticons ( 1F600 - 1F636 )
168   // 6b. Additional transport and map symbols ( 1F681 - 1F6C5 )
169   // 6c. Other additional symbols ( 1F30D - 1F567 )
170
171   if( IsCommonScript( character ) )
172   {
173     return COMMON;
174   }
175
176   if( character <= 0x0cff )
177   {
178     if( character <= 0x09ff )
179     {
180       if( character <= 0x077f )
181       {
182         if( character == 0x00A9 )
183         {
184           return EMOJI; // 5. Uncategorized: copyright sign
185         }
186         if( character == 0x00AE )
187         {
188           return EMOJI; // 5. Uncategorized: registered sign
189         }
190         if( character <= 0x02ff )
191         {
192           return LATIN;
193         }
194         if( ( 0x0370 <= character ) && ( character <= 0x03ff ) )
195         {
196           return GREEK;
197         }
198         if( ( 0x0400 <= character ) && ( character <= 0x04ff ) )
199         {
200           return CYRILLIC;
201         }
202         if( ( 0x0500 <= character ) && ( character <= 0x052f ) )
203         {
204           return CYRILLIC;
205         }
206         if( ( 0x0530 <= character ) && ( character <= 0x058f ) )
207         {
208           return ARMENIAN;
209         }
210         if( ( 0x0591 <= character ) && ( character <= 0x05f4 ) )
211         {
212           return HEBREW;
213         }
214         if( ( 0x0600 <= character ) && ( character <= 0x06ff ) )
215         {
216           return ARABIC;
217         }
218         if( ( 0x0750 <= character ) && ( character <= 0x077f ) )
219         {
220           return ARABIC;
221         }
222       }
223       else // > 0x077f
224       {
225         if( ( 0x08A0 <= character ) && ( character <= 0x08ff ) )
226         {
227           return ARABIC;
228         }
229         if( ( 0x0900 <= character ) && ( character <= 0x097f ) )
230         {
231           return DEVANAGARI;
232         }
233         if( ( 0x0980 <= character ) && ( character <= 0x09ff ) )
234         {
235           return BENGALI;
236         }
237       }
238     }
239     else // > 0x09ff
240     {
241       if( character <= 0x0b7f )
242       {
243         if( ( 0x0a00 <= character ) && ( character <= 0x0a7f ) )
244         {
245           return GURMUKHI;
246         }
247         if( ( 0x0a80 <= character ) && ( character <= 0x0aff ) )
248         {
249           return GUJARATI;
250         }
251         if( ( 0x0b00 <= character ) && ( character <= 0x0b7f ) )
252         {
253           return ORIYA;
254         }
255       }
256       else // > 0x0b7f
257       {
258         if( ( 0x0b80 <= character ) && ( character <= 0x0bff ) )
259         {
260           return TAMIL;
261         }
262         if( ( 0x0c00 <= character ) && ( character <= 0x0c7f ) )
263         {
264           return TELUGU;
265         }
266         if( ( 0x0c80 <= character ) && ( character <= 0x0cff ) )
267         {
268           return KANNADA;
269         }
270       }
271     }
272   }
273   else // > 0x0cff
274   {
275     if( character <= 0x2c7f )
276     {
277       if( character <= 0x1eff )
278       {
279         if( ( 0x0d00 <= character ) && ( character <= 0x0d7f ) )
280         {
281           return MALAYALAM;
282         }
283         if( ( 0x0d80 <= character ) && ( character <= 0x0dff ) )
284         {
285           return SINHALA;
286         }
287         if( ( 0x0e00 <= character ) && ( character <= 0x0e7f ) )
288         {
289           return THAI;
290         }
291         if( ( 0x0e80 <= character ) && ( character <= 0x0eff ) )
292         {
293           return LAO;
294         }
295         if( ( 0x1000 <= character ) && ( character <= 0x109f ) )
296         {
297           return BURMESE;
298         }
299         if( ( 0x10a0 <= character ) && ( character <= 0x10ff ) )
300         {
301           return GEORGIAN;
302         }
303         if( ( 0x1100 <= character ) && ( character <= 0x11ff ) )
304         {
305           return HANGUL;
306         }
307         if( ( 0x1780 <= character ) && ( character <= 0x17ff ) )
308         {
309           return KHMER;
310         }
311         if( ( 0x19e0 <= character ) && ( character <= 0x19ff ) )
312         {
313           return KHMER;
314         }
315         if( ( 0x1d00 <= character ) && ( character <= 0x1eff ) )
316         {
317           return LATIN;
318         }
319       }
320       else // > 0x1eff
321       {
322         if( ( 0x1f00 <= character ) && ( character <= 0x1fff ) )
323         {
324           return GREEK;
325         }
326         if( character == 0x203c )
327         {
328           return EMOJI; // 5. Uncategorized: double exclamation mark
329         }
330         if( character == 0x2049 )
331         {
332           return EMOJI; // 5. Uncategorized: exclamation question mark
333         }
334         if( ( 0x2070 <= character ) && ( character <= 0x209f ) )
335         {
336           return LATIN;
337         }
338         if( character == 0x20e3 )
339         {
340           return EMOJI; // 5. Uncategorized: combining enclosing keycap
341         }
342         if( character == 0x2122 )
343         {
344           return EMOJI; // 5. Uncategorized: trade mark sign
345         }
346         if( character == 0x2139 )
347         {
348           return EMOJI; // 5. Uncategorized: information source
349         }
350         if( ( 0x2100 <= character ) && ( character <= 0x218f ) )
351         {
352           return LATIN;
353         }
354         // U+2194 5. Uncategorized: left right arrow
355         // U+2B55 5. Uncategorized: heavy large circle
356         if( ( 0x2194 <= character ) && ( character <= 0x2B55 ) )
357         {
358           return EMOJI;
359         }
360         if( ( 0x2c60 <= character ) && ( character <= 0x2c7f ) )
361         {
362           return LATIN;
363         }
364       }
365     }
366     else // > 0x2c7f
367     {
368       if( character <= 0xfdff )
369       {
370         if( ( 0x2d00 <= character ) && ( character <= 0x2d2f ) )
371         {
372           return GEORGIAN;
373         }
374         if( ( 0x2de0 <= character ) && ( character <= 0x2dff ) )
375         {
376           return CYRILLIC;
377         }
378         if( ( 0x2e80 <= character ) && ( character <= 0x2eff ) )
379         {
380           return CJK;
381         }
382         if( ( 0x2f00 <= character ) && ( character <= 0x2fdf ) )
383         {
384           return CJK;
385         }
386         if( ( 0x3000 <= character ) && ( character <= 0x303f ) )
387         {
388           return CJK;
389         }
390         if( ( 0x3040 <= character ) && ( character <= 0x309f ) )
391         {
392           return HIRAGANA;
393         }
394         if( ( 0x30a0 <= character ) && ( character <= 0x30ff ) )
395         {
396           return KATAKANA;
397         }
398         if( ( 0x3130 <= character ) && ( character <= 0x318f ) )
399         {
400           return HANGUL;
401         }
402         if( ( 0x3200 <= character ) && ( character <= 0x32ff ) )
403         {
404           return CJK;
405         }
406         if( ( 0x3400 <= character ) && ( character <= 0x4dbf ) )
407         {
408           return CJK;
409         }
410         if( ( 0x4e00 <= character ) && ( character <= 0x62ff ) )
411         {
412           return CJK;
413         }
414         if( ( 0x6300 <= character ) && ( character <= 0x77ff ) )
415         {
416           return CJK;
417         }
418         if( ( 0x7800 <= character ) && ( character <= 0x8cff ) )
419         {
420           return CJK;
421         }
422         if( ( 0x8d00 <= character ) && ( character <= 0x9fff ) )
423         {
424           return CJK;
425         }
426         if( ( 0xa640 <= character ) && ( character <= 0xa69f ) )
427         {
428           return CYRILLIC;
429         }
430         if( ( 0xa720 <= character ) && ( character <= 0xa7ff ) )
431         {
432           return LATIN;
433         }
434         if( ( 0xa960 <= character ) && ( character <= 0xa97f ) )
435         {
436           return HANGUL;
437         }
438         if( ( 0xab30 <= character ) && ( character <= 0xab6f ) )
439         {
440           return LATIN;
441         }
442         if( ( 0xac00 <= character ) && ( character <= 0xd7af ) )
443         {
444           return HANGUL;
445         }
446         if( ( 0xd7b0 <= character ) && ( character <= 0xd7ff ) )
447         {
448           return HANGUL;
449         }
450         if( ( 0xfb00 <= character ) && ( character <= 0xfb06 ) )
451         {
452           return LATIN;
453         }
454         if( ( 0xfb13 <= character ) && ( character <= 0xfb17 ) )
455         {
456           return ARMENIAN;
457         }
458         if( ( 0xfb1d <= character ) && ( character <= 0xfb4f ) )
459         {
460           return HEBREW;
461         }
462         if( ( 0xfb50 <= character ) && ( character <= 0xfdff ) )
463         {
464           return ARABIC;
465         }
466       }
467       else // > 0xfdff
468       {
469         if( ( 0xfe70 <= character ) && ( character <= 0xfeff ) )
470         {
471           return ARABIC;
472         }
473         if( ( 0xff00 <= character ) && ( character <= 0xffef ) )
474         {
475           return LATIN;
476         }
477         if( ( 0x1ee00 <= character ) && ( character <= 0x1eeff ) )
478         {
479           return ARABIC;
480         }
481         // U+1f170 4. Enclosed characters: negative squared latin capital letter A
482         // U+1f6c5 6b. Additional transport and map symbols
483         if( ( 0x1f170 <= character ) && ( character <= 0x1f6c5 ) )
484         {
485           return EMOJI;
486         }
487         if( ( 0x20000 <= character ) && ( character <= 0x215ff ) )
488         {
489           return CJK;
490         }
491         if( ( 0x21600 <= character ) && ( character <= 0x230ff ) )
492         {
493           return CJK;
494         }
495         if( ( 0x23100 <= character ) && ( character <= 0x245ff ) )
496         {
497           return CJK;
498         }
499         if( ( 0x24600 <= character ) && ( character <= 0x260ff ) )
500         {
501           return CJK;
502         }
503         if( ( 0x26100 <= character ) && ( character <= 0x275ff ) )
504         {
505           return CJK;
506         }
507         if( ( 0x27600 <= character ) && ( character <= 0x290ff ) )
508         {
509           return CJK;
510         }
511         if( ( 0x29100 <= character ) && ( character <= 0x2a6df ) )
512         {
513           return CJK;
514         }
515         if( ( 0x2a700 <= character ) && ( character <= 0x2b73f ) )
516         {
517           return CJK;
518         }
519         if( ( 0x2b740 <= character ) && ( character <= 0x2b81f ) )
520         {
521           return CJK;
522         }
523       }
524     }
525   }
526
527   return UNKNOWN;
528 }
529
530 bool IsWhiteSpace( Character character )
531 {
532   return character < WHITE_SPACE_THRESHOLD;
533 }
534
535 bool IsNewParagraph( Character character )
536 {
537   return ( ( CHAR_LF == character )  ||
538            ( CHAR_VT == character )  ||
539            ( CHAR_FF == character )  ||
540            ( CHAR_CR == character )  ||
541            ( CHAR_NEL == character ) ||
542            ( CHAR_LS == character )  ||
543            ( CHAR_PS == character ) );
544 }
545
546 bool IsZeroWidthNonJoiner( Character character )
547 {
548   return CHAR_ZWNJ == character;
549 }
550
551 bool IsZeroWidthJoiner( Character character )
552 {
553   return CHAR_ZWJ == character;
554 }
555
556 bool IsZeroWidthSpace( Character character )
557 {
558   return CHAR_ZWS == character;
559 }
560
561 bool IsLeftToRightMark( Character character )
562 {
563   return CHAR_LTRM == character;
564 }
565
566 bool IsRightToLeftMark( Character character )
567 {
568   return CHAR_RTLM == character;
569 }
570
571 bool IsThinSpace( Character character )
572 {
573   return CHAR_TS == character;
574 }
575
576 bool IsCommonScript( Character character )
577 {
578   return ( IsWhiteSpace( character )         ||
579            IsZeroWidthNonJoiner( character ) ||
580            IsZeroWidthJoiner( character )    ||
581            IsZeroWidthSpace( character )     ||
582            IsLeftToRightMark( character )    ||
583            IsRightToLeftMark( character )    ||
584            IsThinSpace( character )          ||
585            IsNewParagraph( character ) );
586 }
587
588 } // namespace TextAbstraction
589
590 } // namespace Dali