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