Merge "Combine Internal::ProxyObject & Internal::Object" into tizen
[platform/core/uifw/dali-core.git] / dali / internal / event / text / character-impl.cpp
1 /*
2  * Copyright (c) 2014 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 // HEADER CLASS
19 #include <dali/internal/event/text/character-impl.h>
20
21 namespace
22 {
23
24 const unsigned char CHAR_WHITE_SPACE(32);                                   ///< Unsigned characters 0-32 (' ') are white space, 33-127 are standard ASCII, 128+ are UTF-8.
25 const unsigned char CHAR_NEW_LINE( 0x0A );                                  ///< New Line character (LF)
26
27 bool IsCharBidirectional(uint32_t i)
28 {
29   //TODO: Cover the entire table.
30   /*
31     http://www.ietf.org/rfc/rfc3454.txt
32     D. Bidirectional tables
33     D.1 Characters with bidirectional property "R" or "AL"
34     D.2 Characters with bidirectional property "L"
35
36     bidirectional characters are those characters which are neither R (D.1) or L (D.2)
37    */
38   if( i < 0x0041 )
39   {
40     return true;
41   }
42   if( i > 0x005a && i < 0x0061 )
43   {
44     return true;
45   }
46   if( i > 0x007a && i < 0x00aa )
47   {
48     return true;
49   }
50
51   return false;
52 }
53
54 bool IsCharLeftToRight(uint32_t i)
55 {
56   //TODO: This method could be optimized. Performance notes: 1400us for 64k calls (80us for first if statement, 40us for each subsequent if statement)
57   //TODO: This table could be parsed from internet (http://www.unicode.org/Public/6.0.0/ucd/UnicodeData.txt) or a config file.
58   /*
59     http://www.ietf.org/rfc/rfc3454.txt
60     D. Bidirectional tables
61     D.1 Characters with bidirectional property "R" or "AL"
62
63     ----- Start Table D.1 -----
64     05BE
65     05C0
66     05C3
67     05D0-05EA
68     05F0-05F4
69     061B
70     061F
71     0621-063A
72     0640-064A
73     066D-066F
74     0671-06D5
75     06DD
76     06E5-06E6
77     06FA-06FE
78     0700-070D
79     0710
80     0712-072C
81     0780-07A5
82     07B1
83     200F
84     FB1D
85     FB1F-FB28
86     FB2A-FB36
87     FB38-FB3C
88     FB3E
89     FB40-FB41
90     FB43-FB44
91     FB46-FBB1
92     FBD3-FD3D
93     FD50-FD8F
94     FD92-FDC7
95     FDF0-FDFC
96     FE70-FE74
97     FE76-FEFC
98     ----- End Table D.1 -----
99   */
100
101   if( 0x05BE == i )
102   {
103     return false;
104   }
105   if( 0x05C0 == i )
106   {
107     return false;
108   }
109   if( 0x05C3 == i )
110   {
111     return false;
112   }
113   if( ( 0x05D0 <= i ) && ( 0x05EA >= i ) )
114   {
115     return false;
116   }
117   if( ( 0x05F0 <= i ) && ( 0x05F4 >= i ) )
118   {
119     return false;
120   }
121   if( 0x061B == i )
122   {
123     return false;
124   }
125   if( 0x061F == i )
126   {
127     return false;
128   }
129   if( ( 0x0621 <= i ) && ( 0x063A >= i ) )
130   {
131     return false;
132   }
133   if( ( 0x0640 <= i ) && ( 0x064A >= i ) )
134   {
135     return false;
136   }
137   if( ( 0x066D <= i ) && ( 0x066F >= i ) )
138   {
139     return false;
140   }
141   if( ( 0x0671 <= i ) && ( 0x06D5 >= i ) )
142   {
143     return false;
144   }
145   if( 0x06DD == i )
146   {
147     return false;
148   }
149   if( ( 0x06E5 <= i ) && ( 0x06E6 >= i ) )
150   {
151     return false;
152   }
153   if( ( 0x06FA <= i ) && ( 0x06FE >= i ) )
154   {
155     return false;
156   }
157   if( ( 0x0700 <= i ) && ( 0x070D >= i ) )
158   {
159     return false;
160   }
161   if( 0x0710 == i )
162   {
163     return false;
164   }
165   if( ( 0x0712 <= i ) && ( 0x072C >= i ) )
166   {
167     return false;
168   }
169   if( ( 0x0780 <= i ) && ( 0x07A5 >= i ) )
170   {
171     return false;
172   }
173   if( 0x07B1 == i )
174   {
175     return false;
176   }
177   if( 0x200F == i )
178   {
179     return false;
180   }
181   if( 0xFB1D == i )
182   {
183     return false;
184   }
185   if( ( 0xFB1F <= i ) && ( 0xFB28 >= i ) )
186   {
187     return false;
188   }
189   if( ( 0xFB2A <= i ) && ( 0xFB36 >= i ) )
190   {
191     return false;
192   }
193   if( ( 0xFB38 <= i ) && ( 0xFB3C >= i ) )
194   {
195     return false;
196   }
197   if( 0xFB3E == i )
198   {
199     return false;
200   }
201   if( ( 0xFB40 <= i ) && ( 0xFB41 >= i ) )
202   {
203     return false;
204   }
205   if( ( 0xFB43 <= i ) && ( 0xFB44 >= i ) )
206   {
207     return false;
208   }
209   if( ( 0xFB46 <= i ) && ( 0xFBB1 >= i ) )
210   {
211     return false;
212   }
213   if( ( 0xFBD3 <= i ) && ( 0xFD3D >= i ) )
214   {
215     return false;
216   }
217   if( ( 0xFD50 <= i ) && ( 0xFD8F >= i ) )
218   {
219     return false;
220   }
221   if( ( 0xFD92 <= i ) && ( 0xFDC7 >= i ) )
222   {
223     return false;
224   }
225   if( ( 0xFDF0 <= i ) && ( 0xFDFC >= i ) )
226   {
227     return false;
228   }
229   if( ( 0xFE70 <= i ) && ( 0xFE74 >= i ) )
230   {
231     return false;
232   }
233   if( ( 0xFE76 <= i ) && ( 0xFEFC >= i ) )
234   {
235     return false;
236   }
237
238   return true;
239 }
240
241 Dali::Character::Script GetCharacterScript( uint32_t character )
242 {
243   // Latin script:
244   // 0x0000 - 0x007f C0 Controls and Basic Latin
245   // 0x0080 - 0x00ff C1 Controls and Latin-1 Supplement
246   // 0x0100 - 0x017f Latin Extended-A
247   // 0x0180 - 0x024f Latin Extended-B
248   // 0x0250 - 0x02af IPA Extensions
249   // 0x02b0 - 0x02ff Spacing Modifier Letters
250   // 0x1d00 - 0x1d7f Phonetic Extensions
251   // 0x1d80 - 0x1dbf Phonetic Extensions Supplement
252   // 0x1e00 - 0x1eff Latin Extended Additional
253   // 0x2070 - 0x209f Superscripts and Subscripts
254   // 0x2100 - 0x214f Letterlike symbols
255   // 0x2150 - 0x218f Number Forms
256   // 0x2c60 - 0x2c7f Latin Extended-C
257   // 0xa720 - 0xa7ff Latin Extended-D
258   // 0xab30 - 0xab6f Latin Extended-E
259   // 0xfb00 - 0xfb4f Alphabetic Presentation Forms
260   // 0xff00 - 0xffef Halfwidth and Fullwidth Forms
261
262   // Brahmic scripts:
263   // 0x0900 - 0x097f Devanagari
264   // 0x0980 - 0x09ff Bengali
265   // 0x0a00 - 0x0a7f Gurmukhi
266   // 0x0a80 - 0x0aff Gujarati
267   // 0x0b00 - 0x0b7f Oriya
268   // 0x0b80 - 0x0bff Tamil
269   // 0x0c00 - 0x0c7f Telugu
270   // 0x0c80 - 0x0cff Kannada
271   // 0x0d00 - 0x0d7f Malayalam
272
273   // Sinhala script.
274   // 0x0d80 - 0x0dff Sinhala
275
276   // Arabic script.
277   // 0x0600 - 0x06ff
278   // 0x0750 - 0x077f
279   // 0x08A0 - 0x08ff
280   // 0xfb50 - 0xfdff
281   // 0xfe70 - 0xfeff
282   // 0x1ee00 - 0x1eeff
283
284
285   if( character <= 0x0cff )
286   {
287     if( character <= 0x09ff )
288     {
289       if( character <= 0x077f )
290       {
291         if( character <= 0x02ff )
292         {
293           return Dali::Character::LATIN;
294         }
295         if( ( 0x0600 <= character ) && ( character <= 0x06ff ) )
296         {
297           return Dali::Character::ARABIC;
298         }
299         if( ( 0x0750 <= character ) && ( character <= 0x077f ) )
300         {
301           return Dali::Character::ARABIC;
302         }
303       }
304       else
305       {
306         if( ( 0x08A0 <= character ) && ( character <= 0x08ff ) )
307         {
308           return Dali::Character::ARABIC;
309         }
310         if( ( 0x0900 <= character ) && ( character <= 0x097f ) )
311         {
312           return Dali::Character::DEVANAGARI;
313         }
314         if( ( 0x0980 <= character ) && ( character <= 0x09ff ) )
315         {
316           return Dali::Character::BENGALI;
317         }
318       }
319     }
320     else
321     {
322       if( character <= 0x0b7f )
323       {
324         if( ( 0x0a00 <= character ) && ( character <= 0x0a7f ) )
325         {
326           return Dali::Character::GURMUKHI;
327         }
328         if( ( 0x0a80 <= character ) && ( character <= 0x0aff ) )
329         {
330           return Dali::Character::GUJARATI;
331         }
332         if( ( 0x0b00 <= character ) && ( character <= 0x0b7f ) )
333         {
334           return Dali::Character::ORIYA;
335         }
336       }
337       else
338       {
339         if( ( 0x0b80 <= character ) && ( character <= 0x0bff ) )
340         {
341           return Dali::Character::TAMIL;
342         }
343         if( ( 0x0c00 <= character ) && ( character <= 0x0c7f ) )
344         {
345           return Dali::Character::TELUGU;
346         }
347         if( ( 0x0c80 <= character ) && ( character <= 0x0cff ) )
348         {
349           return Dali::Character::KANNADA;
350         }
351       }
352     }
353   }
354   else
355   {
356     if( character <= 0x2c7f )
357     {
358       if( character <= 0x1eff )
359       {
360         if( ( 0x0d00 <= character ) && ( character <= 0x0d7f ) )
361         {
362           return Dali::Character::MALAYALAM;
363         }
364         if( ( 0x0d80 <= character ) && ( character <= 0x0dff ) )
365         {
366           return Dali::Character::SINHALA;
367         }
368         if( ( 0x1d00 <= character ) && ( character <= 0x1eff ) )
369         {
370           return Dali::Character::LATIN;
371         }
372       }
373       else
374       {
375         if( ( 0x2070 <= character ) && ( character <= 0x209f ) )
376         {
377           return Dali::Character::LATIN;
378         }
379         if( ( 0x2100 <= character ) && ( character <= 0x218f ) )
380         {
381           return Dali::Character::LATIN;
382         }
383         if( ( 0x2c60 <= character ) && ( character <= 0x2c7f ) )
384         {
385           return Dali::Character::LATIN;
386         }
387       }
388     }
389     else
390     {
391       if( character <= 0xfdff )
392       {
393         if( ( 0xa720 <= character ) && ( character <= 0xa7ff ) )
394         {
395           return Dali::Character::LATIN;
396         }
397         if( ( 0xab30 <= character ) && ( character <= 0xab6f ) )
398         {
399           return Dali::Character::LATIN;
400         }
401         if( ( 0xfb00 <= character ) && ( character <= 0xfb4f ) )
402         {
403           return Dali::Character::LATIN;
404         }
405         if( ( 0xfb50 <= character ) && ( character <= 0xfdff ) )
406         {
407           return Dali::Character::ARABIC;
408         }
409       }
410       else
411       {
412         if( ( 0xfe70 <= character ) && ( character <= 0xfeff ) )
413         {
414           return Dali::Character::ARABIC;
415         }
416         if( ( 0xff00 <= character ) && ( character <= 0xffef ) )
417         {
418           return Dali::Character::LATIN;
419         }
420         if( ( 0x1ee00 <= character ) && ( character <= 0x1eeff ) )
421         {
422           return Dali::Character::ARABIC;
423         }
424       }
425     }
426   }
427
428   return Dali::Character::UNKNOWN;
429 }
430
431 } // unnamed namespace
432
433 namespace Dali
434 {
435
436 namespace Internal
437 {
438
439 Character::Character( uint32_t character )
440 : mCharacter( character )
441 {
442 }
443
444 Character::~Character()
445 {
446 }
447
448 Character::CharacterDirection Character::GetCharacterDirection(uint32_t character)
449 {
450   //TODO: This method could be optimized, and should cover all 5 types of characters.
451   if( IsCharBidirectional(character) )
452   {
453     return Dali::Character::Neutral;
454   }
455
456   if( IsCharLeftToRight(character) )
457   {
458     return Dali::Character::LeftToRight;
459   }
460
461   return Dali::Character::RightToLeft;
462 }
463
464 Character::CharacterDirection Character::GetCharacterDirection() const
465 {
466   return GetCharacterDirection( mCharacter );
467 }
468
469 Dali::Character::Script Character::GetScript( uint32_t character )
470 {
471   return GetCharacterScript( character );
472 }
473
474 Dali::Character::Script Character::GetScript() const
475 {
476   return GetCharacterScript( mCharacter );
477 }
478
479 bool Character::IsLeftToRight() const
480 {
481   return GetCharacterDirection() != Dali::Character::RightToLeft;
482 }
483
484 bool Character::IsWhiteSpace() const
485 {
486   return Character::IsWhiteSpace( mCharacter );
487 }
488
489 bool Character::IsNewLine() const
490 {
491   return Character::IsNewLine( mCharacter );
492 }
493
494 uint32_t Character::GetCharacter() const
495 {
496   return mCharacter;
497 }
498
499 void Character::SetCharacter( uint32_t character )
500 {
501   mCharacter = character;
502 }
503
504 bool Character::IsWhiteSpace( uint32_t character )
505 {
506   // TODO: It should cover unicode characters: http://en.wikipedia.org/wiki/Whitespace_character
507   return character <= CHAR_WHITE_SPACE;
508 }
509
510 bool Character::IsNewLine( uint32_t character )
511 {
512   return character == CHAR_NEW_LINE;
513 }
514
515 } // namespace Internal
516
517 } // namespace Dali