Sorts text sequences in LTR and RTL by system language direction.
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit / dali-toolkit-test-utils / toolkit-text-abstraction.cpp
1 /*
2  * Copyright (c) 2016 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 #include <dali/devel-api/text-abstraction/bidirectional-support.h>
18 #include <dali/devel-api/text-abstraction/font-client.h>
19 #include <dali/devel-api/text-abstraction/font-metrics.h>
20 #include <dali/devel-api/text-abstraction/glyph-info.h>
21 #include <dali/devel-api/text-abstraction/script.h>
22 #include <dali/devel-api/text-abstraction/segmentation.h>
23 #include <dali/devel-api/text-abstraction/shaping.h>
24 #include <dali/public-api/object/base-object.h>
25 #include <dali/devel-api/adaptor-framework/singleton-service.h>
26 #include <cstring>
27
28 using namespace Dali;
29
30 namespace Dali
31 {
32 class Adaptor;
33
34 namespace TextAbstraction
35 {
36 namespace Internal
37 {
38
39 class BidirectionalSupport : public BaseObject
40 {
41 public:
42   BidirectionalSupport()
43   {
44   }
45
46   ~BidirectionalSupport()
47   {
48   }
49
50   static TextAbstraction::BidirectionalSupport Get()
51   {
52     TextAbstraction::BidirectionalSupport bidirectionalSupportHandle;
53
54     Dali::SingletonService service( Dali::SingletonService::Get() );
55     if( service )
56     {
57       // Check whether the singleton is already created
58       BaseHandle handle = service.GetSingleton( typeid( TextAbstraction::BidirectionalSupport ) );
59       if(handle)
60       {
61         // If so, downcast the handle
62         BidirectionalSupport* impl = dynamic_cast< Internal::BidirectionalSupport* >( handle.GetObjectPtr() );
63         bidirectionalSupportHandle = TextAbstraction::BidirectionalSupport( impl );
64       }
65       else // create and register the object
66       {
67         bidirectionalSupportHandle = TextAbstraction::BidirectionalSupport( new BidirectionalSupport );
68         service.Register( typeid( bidirectionalSupportHandle ), bidirectionalSupportHandle );
69       }
70     }
71     return bidirectionalSupportHandle;
72   }
73   BidiInfoIndex CreateInfo( const Character* const paragraph, Length numberOfCharacters,
74                             bool matchSystemLanguageDirection, LayoutDirection::Type layoutDirection ){return 0;}
75
76   void DestroyInfo( BidiInfoIndex bidiInfoIndex )
77   {
78   }
79
80   void Reorder( BidiInfoIndex bidiInfoIndex,CharacterIndex firstCharacterIndex,Length numberOfCharacters,CharacterIndex* visualToLogicalMap )
81   {
82   }
83
84   bool GetMirroredText( Character* text,CharacterDirection* directions,Length numberOfCharacters )
85   {
86     return true;
87   }
88
89   bool GetParagraphDirection( BidiInfoIndex bidiInfoIndex ) const
90   {
91     return true;
92   }
93
94   void GetCharactersDirection( BidiInfoIndex bidiInfoIndex, CharacterDirection* directions, Length numberOfCharacters )
95   {
96   }
97 }; // class BidirectionalSupport
98
99
100 class FontClient : public BaseObject
101 {
102 public:
103   FontClient()
104   : mDpiHorizontal( 0 ),
105     mDpiVertical( 0 )
106   {
107   }
108
109   ~FontClient(){}
110
111   static Dali::TextAbstraction::FontClient Get()
112   {
113     Dali::TextAbstraction::FontClient fontClientHandle;
114
115     Dali::SingletonService service( SingletonService::Get() );
116     if ( service )
117     {
118       // Check whether the singleton is already created
119       Dali::BaseHandle handle = service.GetSingleton( typeid( Dali::TextAbstraction::FontClient ) );
120       if(handle)
121       {
122         // If so, downcast the handle
123         FontClient* impl = dynamic_cast< Dali::TextAbstraction::Internal::FontClient* >( handle.GetObjectPtr() );
124         fontClientHandle = Dali::TextAbstraction::FontClient( impl );
125       }
126       else // create and register the object
127       {
128         fontClientHandle = Dali::TextAbstraction::FontClient( new FontClient );
129         service.Register( typeid( fontClientHandle ), fontClientHandle );
130       }
131     }
132
133     return fontClientHandle;
134   }
135
136   void SetDpi( unsigned int horizontalDpi, unsigned int verticalDpi ){}
137   void GetDpi( unsigned int& horizontalDpi, unsigned int& verticalDpi ){horizontalDpi=verticalDpi=96;}
138
139   void ResetSystemDefaults(){}
140   void GetDefaultFonts( FontList& defaultFonts ){}
141   void GetDefaultPlatformFontDescription( FontDescription& fontDescription ){}
142   void GetSystemFonts( FontList& systemFonts ){}
143   void GetDescription( FontId id, FontDescription& fontDescription ){}
144   PointSize26Dot6 GetPointSize( FontId id ){return 9;}
145   FontId FindDefaultFont( Character charcode, PointSize26Dot6 pointSize, bool preferColor ){return 0;}
146   FontId FindFallbackFont( Character charcode, const FontDescription& fontDescription, PointSize26Dot6 pointSize, bool preferColor ){return 0;}
147   FontId GetFontId( const FontPath& path, PointSize26Dot6 pointSize, FaceIndex faceIndex ){return 0;}
148   FontId GetFontId( const FontDescription& fontDescription,PointSize26Dot6 pointSize, FaceIndex faceIndex ){return 0;}
149   bool IsScalable( const FontPath& path ){return true;}
150   bool IsScalable( const FontDescription& fontDescription ){return true;}
151   void GetFixedSizes( const FontPath& path, Dali::Vector< PointSize26Dot6>& sizes ){}
152   void GetFixedSizes( const FontDescription& fontDescription, Dali::Vector< PointSize26Dot6 >& sizes ){}
153   void GetFontMetrics( FontId fontId, FontMetrics& metrics ){}
154   GlyphIndex GetGlyphIndex( FontId fontId, Character charcode ){return 0;}
155   bool GetGlyphMetrics( GlyphInfo* array, uint32_t size, bool horizontal ){return true;}
156   void CreateBitmap( FontId fontId, GlyphIndex glyphIndex, bool softwareItailc, bool softwareBold, Dali::TextAbstraction::FontClient::GlyphBufferData& data, int outlineWidth ){}
157   PixelData CreateBitmap( FontId fontId, GlyphIndex glyphIndex, int outlineWidth ){return PixelData();}
158   void CreateVectorBlob( FontId fontId, GlyphIndex glyphIndex, VectorBlob*& blob,
159                          unsigned int& blobLength, unsigned int& nominalWidth, unsigned int& nominalHeight )
160   {
161     blobLength = 0;
162   }
163   const GlyphInfo& GetEllipsisGlyph( PointSize26Dot6 pointSize ){return mGlyphInfo;}
164   bool IsColorGlyph( FontId fontId, GlyphIndex glyphIndex ){return false;}
165 private:
166   unsigned int mDpiHorizontal;
167   unsigned int mDpiVertical;
168   GlyphInfo    mGlyphInfo;
169 }; // class FontClient
170
171
172 class Shaping : public BaseObject
173 {
174 public:
175   Shaping() : mText(NULL)
176   {}
177
178   ~Shaping()
179   {
180     delete [] mText;
181   }
182
183   static Dali::TextAbstraction::Shaping Get()
184   {
185     Dali::TextAbstraction::Shaping shapingHandle;
186
187     Dali::SingletonService service( SingletonService::Get() );
188     if ( service )
189     {
190       // Check whether the singleton is already created
191       Dali::BaseHandle handle = service.GetSingleton( typeid( Dali::TextAbstraction::Shaping ) );
192       if(handle)
193       {
194         // If so, downcast the handle
195         Shaping* impl = dynamic_cast< Dali::TextAbstraction::Internal::Shaping* >( handle.GetObjectPtr() );
196         shapingHandle = Dali::TextAbstraction::Shaping( impl );
197       }
198       else // create and register the object
199       {
200         shapingHandle = Dali::TextAbstraction::Shaping( new Shaping );
201         service.Register( typeid( shapingHandle ), shapingHandle );
202       }
203     }
204     return shapingHandle;
205   }
206
207   void GetGlyphs(GlyphInfo* glyphStore, unsigned int*mappingTable)
208   {
209     // Return store & mapping table (0, 1, 2, 3... N-1))
210     if( glyphStore )
211     {
212       memcpy( glyphStore, mText, mNumChars );
213     }
214     for( unsigned int i=0; i<mNumChars ; ++i )
215     {
216       mappingTable[i] = i;
217     }
218   }
219
220   Length Shape(unsigned int const* text, unsigned int numChars, unsigned int fontId, Script script)
221   {
222     mText = new unsigned char[numChars];
223     mNumChars = numChars;
224
225     memcpy( mText, text, numChars );
226
227     return numChars;
228   }
229 private:
230   unsigned char* mText;
231   unsigned int mNumChars;
232 };
233
234 } // Internal
235 } // TextAbstraction
236
237 inline static TextAbstraction::Internal::BidirectionalSupport& GetImplementation( TextAbstraction::BidirectionalSupport& bidirectionalSupport )
238 {
239   DALI_ASSERT_ALWAYS( bidirectionalSupport && "bidirectional support handle is empty" );
240   BaseObject& object = bidirectionalSupport.GetBaseObject();
241   return static_cast<TextAbstraction::Internal::BidirectionalSupport&>(object);
242 }
243
244 inline static const TextAbstraction::Internal::BidirectionalSupport& GetImplementation( const TextAbstraction::BidirectionalSupport& bidirectionalSupport )
245 {
246   DALI_ASSERT_ALWAYS( bidirectionalSupport && "bidirectional support handle is empty" );
247   const BaseObject& object = bidirectionalSupport.GetBaseObject();
248   return static_cast<const TextAbstraction::Internal::BidirectionalSupport&>(object);
249 }
250
251 inline static TextAbstraction::Internal::FontClient& GetImplementation(TextAbstraction::FontClient& fontClient)
252 {
253   DALI_ASSERT_ALWAYS( fontClient && "fontClient handle is empty" );
254   BaseObject& handle = fontClient.GetBaseObject();
255   return static_cast<TextAbstraction::Internal::FontClient&>(handle);
256 }
257
258 inline static const TextAbstraction::Internal::FontClient& GetImplementation(const TextAbstraction::FontClient& fontClient)
259 {
260   DALI_ASSERT_ALWAYS( fontClient && "fontClient handle is empty" );
261   const BaseObject& handle = fontClient.GetBaseObject();
262   return static_cast<const TextAbstraction::Internal::FontClient&>(handle);
263 }
264
265 inline static TextAbstraction::Internal::Shaping& GetImplementation(TextAbstraction::Shaping& shaping)
266 {
267   DALI_ASSERT_ALWAYS( shaping && "shaping handle is empty" );
268   BaseObject& handle = shaping.GetBaseObject();
269   return static_cast<TextAbstraction::Internal::Shaping&>(handle);
270 }
271
272 inline static const TextAbstraction::Internal::Shaping& GetImplementation(const TextAbstraction::Shaping& shaping)
273 {
274   DALI_ASSERT_ALWAYS( shaping && "shaping handle is empty" );
275   const BaseObject& handle = shaping.GetBaseObject();
276   return static_cast<const TextAbstraction::Internal::Shaping&>(handle);
277 }
278
279
280 ////////////////////////////////////////////////////////////////////////////////
281 /******************************************************************************/
282
283 namespace TextAbstraction
284 {
285 const PointSize26Dot6 FontClient::DEFAULT_POINT_SIZE = 768u; // 12*64
286
287 BidirectionalSupport::BidirectionalSupport()
288 {
289 }
290
291 BidirectionalSupport::~BidirectionalSupport()
292 {
293 }
294
295 BidirectionalSupport::BidirectionalSupport( Internal::BidirectionalSupport* implementation )
296 : BaseHandle( implementation )
297 {
298 }
299
300 BidirectionalSupport BidirectionalSupport::Get()
301 {
302   return Internal::BidirectionalSupport::Get();
303 }
304
305 BidiInfoIndex BidirectionalSupport::CreateInfo( const Character* const paragraph,
306                                                 Length numberOfCharacters,
307                                                 bool matchSystemLanguageDirection,
308                                                 LayoutDirection::Type layoutDirection )
309 {
310   return GetImplementation( *this ).CreateInfo( paragraph, numberOfCharacters, matchSystemLanguageDirection, layoutDirection );
311 }
312
313 void BidirectionalSupport::DestroyInfo( BidiInfoIndex bidiInfoIndex )
314 {
315   GetImplementation( *this ).DestroyInfo( bidiInfoIndex );
316 }
317
318 void BidirectionalSupport::Reorder( BidiInfoIndex bidiInfoIndex,
319                                     CharacterIndex firstCharacterIndex,
320                                     Length numberOfCharacters,
321                                     CharacterIndex* visualToLogicalMap )
322 {
323   GetImplementation( *this ).Reorder( bidiInfoIndex, firstCharacterIndex, numberOfCharacters, visualToLogicalMap );
324 }
325
326 bool BidirectionalSupport::GetMirroredText( Character* text,
327                                             CharacterDirection* directions,
328                                             Length numberOfCharacters )
329 {
330   return GetImplementation( *this ).GetMirroredText( text, directions, numberOfCharacters );
331 }
332
333 bool BidirectionalSupport::GetParagraphDirection( BidiInfoIndex bidiInfoIndex ) const
334 {
335   return GetImplementation( *this ).GetParagraphDirection( bidiInfoIndex );
336 }
337
338 void BidirectionalSupport::GetCharactersDirection( BidiInfoIndex bidiInfoIndex,
339                                                    CharacterDirection* directions,
340                                                    Length numberOfCharacters )
341 {
342   GetImplementation( *this ).GetCharactersDirection( bidiInfoIndex, directions, numberOfCharacters );
343 }
344
345
346 FontClient FontClient::Get()
347 {
348   return Internal::FontClient::Get();
349 }
350
351 FontClient::FontClient()
352 {
353 }
354
355 FontClient::~FontClient()
356 {
357 }
358
359 FontClient::FontClient( const FontClient& handle )
360 : BaseHandle( handle )
361 {
362 }
363
364 FontClient::GlyphBufferData::GlyphBufferData()
365 {
366 }
367
368 FontClient::GlyphBufferData::~GlyphBufferData()
369 {
370 }
371
372 FontClient& FontClient::operator=( const FontClient& handle )
373 {
374   BaseHandle::operator=( handle );
375   return *this;
376 }
377
378 void FontClient::SetDpi( unsigned int horizontalDpi, unsigned int verticalDpi  )
379 {
380   GetImplementation(*this).SetDpi( horizontalDpi, verticalDpi );
381 }
382
383 void FontClient::GetDpi( unsigned int& horizontalDpi, unsigned int& verticalDpi )
384 {
385   GetImplementation(*this).GetDpi( horizontalDpi, verticalDpi );
386 }
387
388 void FontClient::ResetSystemDefaults()
389 {
390   GetImplementation(*this).ResetSystemDefaults();
391 }
392
393 void FontClient::GetDefaultFonts( FontList& defaultFonts )
394 {
395   GetImplementation(*this).GetDefaultFonts( defaultFonts );
396 }
397
398 void FontClient::GetDefaultPlatformFontDescription( FontDescription& fontDescription )
399 {
400   GetImplementation(*this).GetDefaultPlatformFontDescription( fontDescription );
401 }
402
403 void FontClient::GetSystemFonts( FontList& systemFonts )
404 {
405   GetImplementation(*this).GetSystemFonts( systemFonts );
406 }
407
408 void FontClient::GetDescription( FontId id, FontDescription& fontDescription )
409 {
410   GetImplementation(*this).GetDescription( id, fontDescription );
411 }
412
413 PointSize26Dot6 FontClient::GetPointSize( FontId id )
414 {
415   return GetImplementation(*this).GetPointSize( id );
416 }
417
418 FontId FontClient::FindDefaultFont( Character charcode, PointSize26Dot6 pointSize, bool preferColor )
419 {
420   return GetImplementation(*this).FindDefaultFont( charcode, pointSize, preferColor );
421 }
422
423 FontId FontClient::FindFallbackFont( Character charcode, const FontDescription& fontDescription, PointSize26Dot6 pointSize, bool preferColor )
424 {
425   return GetImplementation(*this).FindFallbackFont( charcode, fontDescription, pointSize, preferColor );
426 }
427
428 FontId FontClient::GetFontId( const FontPath& path, PointSize26Dot6 pointSize, FaceIndex faceIndex )
429 {
430   return GetImplementation(*this).GetFontId( path, pointSize, faceIndex );
431 }
432
433 FontId FontClient::GetFontId( const FontDescription& fontDescription,
434                               PointSize26Dot6 pointSize,
435                               FaceIndex faceIndex )
436 {
437   return GetImplementation(*this).GetFontId( fontDescription,
438                                              pointSize,
439                                              faceIndex );
440 }
441
442 bool FontClient::IsScalable( const FontPath& path )
443 {
444   return GetImplementation(*this).IsScalable( path );
445 }
446
447 bool FontClient::IsScalable( const FontDescription& fontDescription )
448 {
449   return GetImplementation(*this).IsScalable( fontDescription );
450 }
451
452 void FontClient::GetFixedSizes( const FontPath& path, Dali::Vector< PointSize26Dot6>& sizes )
453 {
454   GetImplementation(*this).GetFixedSizes( path, sizes );
455 }
456
457 void FontClient::GetFixedSizes( const FontDescription& fontDescription,
458                                 Dali::Vector< PointSize26Dot6 >& sizes )
459 {
460   GetImplementation(*this).GetFixedSizes( fontDescription, sizes );
461 }
462
463 void FontClient::GetFontMetrics( FontId fontId, FontMetrics& metrics )
464 {
465   GetImplementation(*this).GetFontMetrics( fontId, metrics );
466 }
467
468 GlyphIndex FontClient::GetGlyphIndex( FontId fontId, Character charcode )
469 {
470   return GetImplementation(*this).GetGlyphIndex( fontId, charcode );
471 }
472
473 bool FontClient::GetGlyphMetrics( GlyphInfo* array, uint32_t size, GlyphType type, bool horizontal )
474 {
475   return GetImplementation(*this).GetGlyphMetrics( array, size, horizontal );
476 }
477
478 void FontClient::CreateBitmap( FontId fontId, GlyphIndex glyphIndex, bool softwareItailc, bool softwareBold, Dali::TextAbstraction::FontClient::GlyphBufferData& data, int outlineWidth )
479 {
480   GetImplementation(*this).CreateBitmap( fontId, glyphIndex, softwareItailc, softwareBold, data, outlineWidth );
481 }
482
483 PixelData FontClient::CreateBitmap( FontId fontId, GlyphIndex glyphIndex, int outlineWidth )
484 {
485   return GetImplementation(*this).CreateBitmap( fontId, glyphIndex, outlineWidth );
486 }
487
488 void FontClient::CreateVectorBlob( FontId fontId,
489                                    GlyphIndex glyphIndex,
490                                    VectorBlob*& blob,
491                                    unsigned int& blobLength,
492                                    unsigned int& nominalWidth,
493                                    unsigned int& nominalHeight )
494 {
495   GetImplementation(*this).CreateVectorBlob( fontId, glyphIndex, blob, blobLength, nominalWidth, nominalHeight );
496 }
497
498 const GlyphInfo& FontClient::GetEllipsisGlyph( PointSize26Dot6 pointSize )
499 {
500   return GetImplementation(*this).GetEllipsisGlyph( pointSize );
501 }
502
503 bool FontClient::IsColorGlyph( FontId fontId, GlyphIndex glyphIndex )
504 {
505   return GetImplementation(*this).IsColorGlyph( fontId, glyphIndex );
506 }
507
508 FontClient::FontClient( Internal::FontClient* internal )
509 : BaseHandle( internal )
510 {
511 }
512
513 FontMetrics::FontMetrics()
514 : ascender( 0.f ),
515   descender( 0.f ),
516   height( 0.f ),
517   underlinePosition( 0.f ),
518   underlineThickness( 0.f )
519 {
520 }
521
522 GlyphInfo::GlyphInfo()
523 {
524 }
525
526 Script GetCharacterScript(unsigned int x)
527 {
528   return LATIN;
529 }
530 bool HasLigatureMustBreak(Script x){return false;}
531 bool IsCommonScript(unsigned int character){ return false;}
532 bool IsNewParagraph(unsigned int character){return false;}
533 bool IsRightToLeftScript(Script){return false;}
534 bool IsWhiteSpace(unsigned int character)
535 {
536   return character < 0x21;
537 }
538
539 Segmentation Segmentation::Get(){ return Segmentation();}
540 Segmentation::Segmentation(){}
541 Segmentation::~Segmentation(){}
542 void Segmentation::GetLineBreakPositions(unsigned int const*, unsigned int, char*){}
543 void Segmentation::GetWordBreakPositions(unsigned int const*, unsigned int, char*){}
544
545 Shaping Shaping::Get()
546 {
547   return TextAbstraction::Internal::Shaping::Get();
548 }
549
550 Shaping::Shaping()
551 {
552 }
553
554 Shaping::Shaping( Internal::Shaping* internal )
555 : BaseHandle( internal )
556 {
557 }
558
559 Shaping::~Shaping()
560 {
561 }
562
563 void Shaping::GetGlyphs(GlyphInfo* glyphStore, unsigned int*mappingTable)
564 {
565   // Return store & mapping table (0, 1, 2, 3... N-1))
566   GetImplementation(*this).GetGlyphs(glyphStore, mappingTable);
567 }
568
569 Length Shaping::Shape(unsigned int const* text, unsigned int numChars, unsigned int fontId, Script script)
570 {
571   return GetImplementation(*this).Shape( text, numChars, fontId, script );
572 }
573
574 } // TextAbstraction
575 } // Dali