[dali_2.3.24] Merge branch 'devel/master'
[platform/core/uifw/dali-adaptor.git] / automated-tests / src / dali-adaptor-internal / utc-Dali-FontClient.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 #include <iostream>
19
20 #include <dali-test-suite-utils.h>
21 #include <dali/dali.h>
22 #include <dali/devel-api/text-abstraction/bitmap-font.h>
23 #include <dali/devel-api/text-abstraction/font-client.h>
24 #include <dali/internal/text/text-abstraction/plugin/font-client-utils.h>
25 #include <stdint.h>
26 #include <stdlib.h>
27 #include <unistd.h>
28 #include <iostream>
29
30 using namespace Dali;
31
32 int UtcDaliFontClient(void)
33 {
34   const int ORDERED_VALUES[] = {-1, 50, 63, 75, 87, 100, 113, 125, 150, 200};
35
36   const unsigned int NUM_OF_ORDERED_VALUES = sizeof(ORDERED_VALUES) / sizeof(int);
37
38   TestApplication application;
39   int             result = 0;
40
41   tet_infoline("UtcDaliFontClient No table");
42   result = TextAbstraction::Internal::ValueToIndex(100, NULL, 0u);
43   DALI_TEST_EQUALS(-1, result, TEST_LOCATION);
44
45   tet_infoline("UtcDaliFontClient Non defined values");
46   result = TextAbstraction::Internal::ValueToIndex(-1, ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u);
47   DALI_TEST_EQUALS(0, result, TEST_LOCATION);
48   result = TextAbstraction::Internal::ValueToIndex(-3, ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u);
49   DALI_TEST_EQUALS(0, result, TEST_LOCATION);
50
51   tet_infoline("UtcDaliFontClient Between non defined and first of range.");
52   result = TextAbstraction::Internal::ValueToIndex(0, ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u);
53   DALI_TEST_EQUALS(1, result, TEST_LOCATION);
54   result = TextAbstraction::Internal::ValueToIndex(30, ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u);
55   DALI_TEST_EQUALS(1, result, TEST_LOCATION);
56   result = TextAbstraction::Internal::ValueToIndex(49, ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u);
57   DALI_TEST_EQUALS(1, result, TEST_LOCATION);
58
59   tet_infoline("UtcDaliFontClient Defined in range");
60   for(unsigned int index = 1u; index < NUM_OF_ORDERED_VALUES; ++index)
61   {
62     result = TextAbstraction::Internal::ValueToIndex(ORDERED_VALUES[index], ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u);
63     DALI_TEST_EQUALS(index, result, TEST_LOCATION);
64   }
65
66   tet_infoline("UtcDaliFontClient Non defined in range");
67   result = TextAbstraction::Internal::ValueToIndex(51, ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u);
68   DALI_TEST_EQUALS(1, result, TEST_LOCATION);
69   result = TextAbstraction::Internal::ValueToIndex(55, ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u);
70   DALI_TEST_EQUALS(1, result, TEST_LOCATION);
71   result = TextAbstraction::Internal::ValueToIndex(62, ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u);
72   DALI_TEST_EQUALS(2, result, TEST_LOCATION);
73   result = TextAbstraction::Internal::ValueToIndex(64, ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u);
74   DALI_TEST_EQUALS(2, result, TEST_LOCATION);
75   result = TextAbstraction::Internal::ValueToIndex(151, ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u);
76   DALI_TEST_EQUALS(8, result, TEST_LOCATION);
77   result = TextAbstraction::Internal::ValueToIndex(175, ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u);
78   DALI_TEST_EQUALS(9, result, TEST_LOCATION);
79   result = TextAbstraction::Internal::ValueToIndex(176, ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u);
80   DALI_TEST_EQUALS(9, result, TEST_LOCATION);
81   result = TextAbstraction::Internal::ValueToIndex(199, ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u);
82   DALI_TEST_EQUALS(9, result, TEST_LOCATION);
83
84   tet_infoline("UtcDaliFontClient above of range");
85   result = TextAbstraction::Internal::ValueToIndex(220, ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u);
86   DALI_TEST_EQUALS(9, result, TEST_LOCATION);
87   result = TextAbstraction::Internal::ValueToIndex(500, ORDERED_VALUES, NUM_OF_ORDERED_VALUES - 1u);
88   DALI_TEST_EQUALS(9, result, TEST_LOCATION);
89
90   END_TEST;
91 }
92
93 int UtcDaliFontClientNew(void)
94 {
95   TestApplication application;
96
97   TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
98   fontClient.SetDpi(30, 40);
99   TextAbstraction::FontClient anotherClient = TextAbstraction::FontClient::New(50, 60);
100
101   uint32_t horizontalDpi;
102   uint32_t verticalDpi;
103
104   tet_printf("Check default font client set dpi well\n");
105   fontClient.GetDpi(horizontalDpi, verticalDpi);
106
107   DALI_TEST_EQUALS(30, horizontalDpi, TEST_LOCATION);
108   DALI_TEST_EQUALS(40, verticalDpi, TEST_LOCATION);
109
110   tet_printf("Check another font client set dpi well\n");
111   anotherClient.GetDpi(horizontalDpi, verticalDpi);
112
113   DALI_TEST_EQUALS(50, horizontalDpi, TEST_LOCATION);
114   DALI_TEST_EQUALS(60, verticalDpi, TEST_LOCATION);
115
116   END_TEST;
117 }
118 int UtcDaliFontClientAtlasLimitation(void)
119 {
120   TestApplication             application;
121   bool                        result     = 0;
122   TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
123
124   tet_infoline("UtcDaliFontClientAtlasLimitation Default");
125   result = fontClient.IsAtlasLimitationEnabled();
126   DALI_TEST_EQUALS(TextAbstraction::FontClient::DEFAULT_ATLAS_LIMITATION_ENABLED, result, TEST_LOCATION);
127
128   tet_infoline("UtcDaliFontClientAtlasLimitation Enabled");
129   fontClient.EnableAtlasLimitation(true);
130   result = fontClient.IsAtlasLimitationEnabled();
131   DALI_TEST_EQUALS(true, result, TEST_LOCATION);
132
133   tet_infoline("UtcDaliFontClientAtlasLimitation Disabled");
134   fontClient.EnableAtlasLimitation(false);
135   result = fontClient.IsAtlasLimitationEnabled();
136   DALI_TEST_EQUALS(false, result, TEST_LOCATION);
137   END_TEST;
138 }
139
140 const std::string DEFAULT_FONT_DIR("/resources/fonts");
141 const uint32_t    MAX_WIDTH_FIT_IN_ATLAS  = TextAbstraction::FontClient::MAX_TEXT_ATLAS_WIDTH - TextAbstraction::FontClient::PADDING_TEXT_ATLAS_BLOCK;
142 const uint32_t    MAX_HEIGHT_FIT_IN_ATLAS = TextAbstraction::FontClient::MAX_TEXT_ATLAS_HEIGHT - TextAbstraction::FontClient::PADDING_TEXT_ATLAS_BLOCK;
143
144 int UtcDaliFontClientAtlasLimitationEnabled(void)
145 {
146   TestApplication application;
147
148   char*             pathNamePtr = get_current_dir_name();
149   const std::string pathName(pathNamePtr);
150   free(pathNamePtr);
151
152   TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
153   fontClient.EnableAtlasLimitation(true);
154
155   // The font file "DejaVuSans.ttf" is copied from Toolkit to Adaptor to make test-case of specific font-family.
156   // Note the block size depends on font-family.
157   // This is to create FontDescription and pass it to GetFontId with point-size (various cases).
158   TextAbstraction::FontDescription fontDescription;
159   fontDescription.path   = pathName + DEFAULT_FONT_DIR + "/dejavu/DejaVuSans.ttf";
160   fontDescription.family = "DejaVuSans";
161   fontDescription.width  = TextAbstraction::FontWidth::NONE;
162   fontDescription.weight = TextAbstraction::FontWeight::NORMAL;
163   fontDescription.slant  = TextAbstraction::FontSlant::NONE;
164
165   // Block's width or height are less than 512
166   tet_infoline("UtcDaliFontClientAtlasLimitationEnabled PointSize=200");
167   uint32_t                         pointSize200 = 200 * TextAbstraction::FontClient::NUMBER_OF_POINTS_PER_ONE_UNIT_OF_POINT_SIZE;
168   TextAbstraction::FontId          fontId200    = fontClient.GetFontId(fontDescription, pointSize200);
169   TextAbstraction::GlyphBufferData glyphBufferData200;
170   glyphBufferData200.width  = 0;
171   glyphBufferData200.height = 0;
172   fontClient.CreateBitmap(fontId200, 68, false, false, glyphBufferData200, 0);
173
174   DALI_TEST_GREATER(MAX_WIDTH_FIT_IN_ATLAS, glyphBufferData200.width, TEST_LOCATION);
175   DALI_TEST_GREATER(MAX_HEIGHT_FIT_IN_ATLAS, glyphBufferData200.height, TEST_LOCATION);
176
177   // Block's width or height are  greater than 512 and less than 1024
178   uint32_t pointSize1000 = 1000 * TextAbstraction::FontClient::NUMBER_OF_POINTS_PER_ONE_UNIT_OF_POINT_SIZE;
179   tet_infoline("UtcDaliFontClientAtlasLimitationEnabled PointSize=1000");
180   TextAbstraction::FontId          fontId1000 = fontClient.GetFontId(fontDescription, pointSize1000);
181   TextAbstraction::GlyphBufferData glyphBufferData1000;
182   glyphBufferData1000.width  = 0;
183   glyphBufferData1000.height = 0;
184   fontClient.CreateBitmap(fontId1000, 68, false, false, glyphBufferData1000, 0);
185
186   DALI_TEST_GREATER(MAX_WIDTH_FIT_IN_ATLAS, glyphBufferData1000.width, TEST_LOCATION);
187   DALI_TEST_GREATER(MAX_HEIGHT_FIT_IN_ATLAS, glyphBufferData1000.height, TEST_LOCATION);
188
189   // Block's width or height are greater than 1024 and less than 2048
190   uint32_t pointSize2000 = 2000 * TextAbstraction::FontClient::NUMBER_OF_POINTS_PER_ONE_UNIT_OF_POINT_SIZE;
191   tet_infoline("UtcDaliFontClientAtlasLimitationEnabled PointSize=2000");
192   TextAbstraction::FontId          fontId2000 = fontClient.GetFontId(fontDescription, pointSize2000);
193   TextAbstraction::GlyphBufferData glyphBufferData2000;
194   glyphBufferData2000.width  = 0;
195   glyphBufferData2000.height = 0;
196   fontClient.CreateBitmap(fontId2000, 68, false, false, glyphBufferData2000, 0);
197
198   DALI_TEST_GREATER(MAX_WIDTH_FIT_IN_ATLAS, glyphBufferData2000.width, TEST_LOCATION);
199   DALI_TEST_GREATER(MAX_HEIGHT_FIT_IN_ATLAS, glyphBufferData2000.height, TEST_LOCATION);
200
201   END_TEST;
202 }
203
204 int UtcDaliFontClientAtlasLimitationDisabled(void)
205 {
206   TestApplication application;
207
208   char*             pathNamePtr = get_current_dir_name();
209   const std::string pathName(pathNamePtr);
210   free(pathNamePtr);
211
212   TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
213   fontClient.EnableAtlasLimitation(false);
214
215   TextAbstraction::FontDescription fontDescription;
216   fontDescription.path   = pathName + DEFAULT_FONT_DIR + "/dejavu/DejaVuSans.ttf";
217   fontDescription.family = "DejaVuSans";
218   fontDescription.width  = TextAbstraction::FontWidth::NONE;
219   fontDescription.weight = TextAbstraction::FontWeight::NORMAL;
220   fontDescription.slant  = TextAbstraction::FontSlant::NONE;
221
222   // Block's width or height are less than 512
223   tet_infoline("UtcDaliFontClientAtlasLimitationDisabled PointSize=200");
224   uint32_t                         pointSize200 = 200 * TextAbstraction::FontClient::NUMBER_OF_POINTS_PER_ONE_UNIT_OF_POINT_SIZE;
225   TextAbstraction::FontId          fontId200    = fontClient.GetFontId(fontDescription, pointSize200);
226   TextAbstraction::GlyphBufferData glyphBufferData200;
227   glyphBufferData200.width  = 0;
228   glyphBufferData200.height = 0;
229   fontClient.CreateBitmap(fontId200, 68, false, false, glyphBufferData200, 0);
230
231   DALI_TEST_GREATER(512u, glyphBufferData200.width, TEST_LOCATION);  //93u
232   DALI_TEST_GREATER(512u, glyphBufferData200.height, TEST_LOCATION); //115u
233
234   // Block's width or height are  greater than 512 and less than 1024
235   tet_infoline("UtcDaliFontClientAtlasLimitationDisabled PointSize=1000");
236   uint32_t                         pointSize1000 = 1000 * TextAbstraction::FontClient::NUMBER_OF_POINTS_PER_ONE_UNIT_OF_POINT_SIZE;
237   TextAbstraction::FontId          fontId1000    = fontClient.GetFontId(fontDescription, pointSize1000);
238   TextAbstraction::GlyphBufferData glyphBufferData1000;
239   glyphBufferData1000.width  = 0;
240   glyphBufferData1000.height = 0;
241   fontClient.CreateBitmap(fontId1000, 68, false, false, glyphBufferData1000, 0);
242
243   DALI_TEST_GREATER(512u, glyphBufferData1000.width, TEST_LOCATION);  //462u
244   DALI_TEST_GREATER(glyphBufferData1000.height, 512u, TEST_LOCATION); //574u
245
246   // Block's width or height are greater than 1024 and less than 2048
247   tet_infoline("UtcDaliFontClientAtlasLimitationDisabled PointSize=2000");
248   uint32_t                         pointSize2000 = 2000 * TextAbstraction::FontClient::NUMBER_OF_POINTS_PER_ONE_UNIT_OF_POINT_SIZE;
249   TextAbstraction::FontId          fontId2000    = fontClient.GetFontId(fontDescription, pointSize2000);
250   TextAbstraction::GlyphBufferData glyphBufferData2000;
251   glyphBufferData2000.width  = 0;
252   glyphBufferData2000.height = 0;
253   fontClient.CreateBitmap(fontId2000, 68, false, false, glyphBufferData2000, 0);
254
255   DALI_TEST_GREATER(1024u, glyphBufferData2000.width, TEST_LOCATION);  //924u
256   DALI_TEST_GREATER(glyphBufferData2000.height, 1024u, TEST_LOCATION); //1148u
257
258   // Test GlyphBufferData move
259   TextAbstraction::GlyphBufferData movedGlyphBufferData2000 = std::move(glyphBufferData2000);
260
261   for(int i = 0; i < 50; ++i)
262   {
263     TextAbstraction::GlyphBufferData dummy = std::move(movedGlyphBufferData2000);
264     movedGlyphBufferData2000               = std::move(dummy);
265
266     // Test moved GlyphBufferData destruct well
267   }
268
269   DALI_TEST_GREATER(1024u, movedGlyphBufferData2000.width, TEST_LOCATION);  //924u
270   DALI_TEST_GREATER(movedGlyphBufferData2000.height, 1024u, TEST_LOCATION); //1148u
271
272   END_TEST;
273 }
274
275 int UtcDaliFontClientCurrentMaximumBlockSizeFitInAtlas(void)
276 {
277   TestApplication application;
278   tet_infoline(" UtcDaliFontClientCurrentMaximumBlockSizeFitInAtlas ");
279
280   bool                        isChanged;
281   TextAbstraction::FontClient fontClient;
282   fontClient = TextAbstraction::FontClient::Get();
283
284   Size defaultTextAtlasSize              = fontClient.GetDefaultTextAtlasSize();
285   Size maximumTextAtlasSize              = fontClient.GetMaximumTextAtlasSize();
286   Size currentMaximumBlockSizeFitInAtlas = fontClient.GetCurrentMaximumBlockSizeFitInAtlas();
287
288   // TODO : This UTC pass only if we don't create fontClient plugin. Currently we always create plugin at Get API, due to performance
289   //tet_infoline("CurrentMaximumBlockSizeFitInAtlas start with default ");
290   //DALI_TEST_EQUALS(currentMaximumBlockSizeFitInAtlas, defaultTextAtlasSize, TEST_LOCATION);
291
292   currentMaximumBlockSizeFitInAtlas = defaultTextAtlasSize;
293
294   tet_infoline("SetCurrentMaximumBlockSizeFitInAtlas is changed with current ");
295   isChanged = fontClient.SetCurrentMaximumBlockSizeFitInAtlas(currentMaximumBlockSizeFitInAtlas);
296   DALI_TEST_CHECK(isChanged);
297
298   Size decreaseOnlyWidth(currentMaximumBlockSizeFitInAtlas.width - 1u, currentMaximumBlockSizeFitInAtlas.height);
299   tet_infoline("SetCurrentMaximumBlockSizeFitInAtlas is changed with width < current ");
300   isChanged = fontClient.SetCurrentMaximumBlockSizeFitInAtlas(decreaseOnlyWidth);
301   DALI_TEST_CHECK(isChanged);
302
303   Size decreaseOnlyHeigth(currentMaximumBlockSizeFitInAtlas.width, currentMaximumBlockSizeFitInAtlas.height - 1u);
304   tet_infoline("SetCurrentMaximumBlockSizeFitInAtlas is changed with height < current ");
305   isChanged = fontClient.SetCurrentMaximumBlockSizeFitInAtlas(decreaseOnlyHeigth);
306   DALI_TEST_CHECK(isChanged);
307
308   Size decreaseBoth(currentMaximumBlockSizeFitInAtlas.width - 1u, currentMaximumBlockSizeFitInAtlas.height - 1u);
309   tet_infoline("SetCurrentMaximumBlockSizeFitInAtlas is changed with size < current ");
310   isChanged = fontClient.SetCurrentMaximumBlockSizeFitInAtlas(decreaseBoth);
311   DALI_TEST_CHECK(isChanged);
312
313   Size increaseOnlyWidth(maximumTextAtlasSize.width + 1u, currentMaximumBlockSizeFitInAtlas.height);
314   tet_infoline("SetCurrentMaximumBlockSizeFitInAtlas is not changed with width > max ");
315   isChanged = fontClient.SetCurrentMaximumBlockSizeFitInAtlas(increaseOnlyWidth);
316   DALI_TEST_CHECK(!isChanged);
317
318   Size increaseOnlyHeigth(currentMaximumBlockSizeFitInAtlas.width, maximumTextAtlasSize.height + 1u);
319   tet_infoline("SetCurrentMaximumBlockSizeFitInAtlas is not changed with height > max ");
320   isChanged = fontClient.SetCurrentMaximumBlockSizeFitInAtlas(increaseOnlyHeigth);
321   DALI_TEST_CHECK(!isChanged);
322
323   Size increaseBoth(maximumTextAtlasSize.width + 1u, maximumTextAtlasSize.height + 1u);
324   tet_infoline("SetCurrentMaximumBlockSizeFitInAtlas is not changed with size > max ");
325   isChanged = fontClient.SetCurrentMaximumBlockSizeFitInAtlas(increaseBoth);
326   DALI_TEST_CHECK(!isChanged);
327
328   currentMaximumBlockSizeFitInAtlas = fontClient.GetCurrentMaximumBlockSizeFitInAtlas();
329   if(currentMaximumBlockSizeFitInAtlas.width < maximumTextAtlasSize.width && currentMaximumBlockSizeFitInAtlas.height < maximumTextAtlasSize.height)
330   {
331     tet_infoline("SetCurrentMaximumBlockSizeFitInAtlas is changed with current < size < max ");
332     Size increaseWidth = Size(currentMaximumBlockSizeFitInAtlas.width + 1u, currentMaximumBlockSizeFitInAtlas.height);
333     isChanged          = fontClient.SetCurrentMaximumBlockSizeFitInAtlas(increaseWidth);
334     DALI_TEST_CHECK(isChanged);
335     currentMaximumBlockSizeFitInAtlas = fontClient.GetCurrentMaximumBlockSizeFitInAtlas();
336
337     Size increaseHeigth = Size(currentMaximumBlockSizeFitInAtlas.width, currentMaximumBlockSizeFitInAtlas.height + 1u);
338     isChanged           = fontClient.SetCurrentMaximumBlockSizeFitInAtlas(increaseHeigth);
339     DALI_TEST_CHECK(isChanged);
340     currentMaximumBlockSizeFitInAtlas = fontClient.GetCurrentMaximumBlockSizeFitInAtlas();
341
342     Size sizeLessThanMax = Size(currentMaximumBlockSizeFitInAtlas.width + 1u, currentMaximumBlockSizeFitInAtlas.height + 1u);
343     isChanged            = fontClient.SetCurrentMaximumBlockSizeFitInAtlas(sizeLessThanMax);
344
345     if(currentMaximumBlockSizeFitInAtlas.width < maximumTextAtlasSize.width && currentMaximumBlockSizeFitInAtlas.height < maximumTextAtlasSize.height)
346     {
347       DALI_TEST_CHECK(isChanged);
348     }
349     else
350     {
351       DALI_TEST_CHECK(!isChanged);
352     }
353
354     currentMaximumBlockSizeFitInAtlas = fontClient.GetCurrentMaximumBlockSizeFitInAtlas();
355
356     DALI_TEST_NOT_EQUALS(currentMaximumBlockSizeFitInAtlas, defaultTextAtlasSize, 0.0f, TEST_LOCATION);
357     DALI_TEST_EQUALS(currentMaximumBlockSizeFitInAtlas, sizeLessThanMax, TEST_LOCATION);
358
359     tet_infoline("SetCurrentMaximumBlockSizeFitInAtlas is not changed with size == max ");
360     isChanged = fontClient.SetCurrentMaximumBlockSizeFitInAtlas(maximumTextAtlasSize);
361     DALI_TEST_CHECK(!isChanged);
362   }
363
364   currentMaximumBlockSizeFitInAtlas = fontClient.GetCurrentMaximumBlockSizeFitInAtlas();
365   DALI_TEST_NOT_EQUALS(currentMaximumBlockSizeFitInAtlas, maximumTextAtlasSize, 0.0f, TEST_LOCATION);
366
367   END_TEST;
368 }
369
370 int UtcDaliFontClientTextAtlasConstants(void)
371 {
372   TestApplication application;
373   tet_infoline(" UtcDaliFontClientTextAtlasConstants ");
374
375   TextAbstraction::FontClient fontClient;
376   fontClient = TextAbstraction::FontClient::Get();
377
378   Size defaultTextAtlasSize = fontClient.GetDefaultTextAtlasSize();
379   Size defaultTextAtlasWidthHeight(TextAbstraction::FontClient::DEFAULT_TEXT_ATLAS_WIDTH, TextAbstraction::FontClient::DEFAULT_TEXT_ATLAS_HEIGHT);
380   DALI_TEST_EQUALS(defaultTextAtlasSize, TextAbstraction::FontClient::DEFAULT_TEXT_ATLAS_SIZE, TEST_LOCATION);
381   DALI_TEST_EQUALS(defaultTextAtlasSize, defaultTextAtlasWidthHeight, TEST_LOCATION);
382
383   Size maximumTextAtlasSize = fontClient.GetMaximumTextAtlasSize();
384   Size maxTextAtlasWidthHeight(TextAbstraction::FontClient::MAX_TEXT_ATLAS_WIDTH, TextAbstraction::FontClient::MAX_TEXT_ATLAS_HEIGHT);
385   DALI_TEST_EQUALS(maximumTextAtlasSize, TextAbstraction::FontClient::MAX_TEXT_ATLAS_SIZE, TEST_LOCATION);
386   DALI_TEST_EQUALS(maximumTextAtlasSize, maxTextAtlasWidthHeight, TEST_LOCATION);
387
388   uint32_t numberOfPointsPerOneUnitOfPointSize = fontClient.GetNumberOfPointsPerOneUnitOfPointSize();
389   DALI_TEST_EQUALS(numberOfPointsPerOneUnitOfPointSize, TextAbstraction::FontClient::NUMBER_OF_POINTS_PER_ONE_UNIT_OF_POINT_SIZE, TEST_LOCATION);
390
391   END_TEST;
392 }
393
394 using namespace Dali::TextAbstraction;
395
396 int UtcDaliFontClientGetDefaultFonts(void)
397 {
398   TestApplication application;
399   tet_infoline(" UtcDaliFontClientGetDefaultFonts ");
400
401   FontClient fontClient;
402   fontClient = FontClient::Get();
403
404   FontList fontList;
405   fontClient.GetDefaultFonts(fontList);
406
407   std::ostringstream oss;
408   oss << fontList << std::endl;
409
410   tet_printf("FontList: %s", oss.str().c_str());
411   DALI_TEST_CHECK(fontList.size() > 0);
412
413   END_TEST;
414 }
415
416 int UtcDaliFontClientGetSystemFonts(void)
417 {
418   TestApplication application;
419   tet_infoline(" UtcDaliFontClientGetSystemFonts ");
420
421   FontClient fontClient;
422   fontClient = FontClient::Get();
423
424   FontList fontList;
425   fontClient.GetSystemFonts(fontList);
426
427   std::ostringstream oss;
428   oss << fontList << std::endl;
429
430   tet_printf("FontList: %s", oss.str().c_str());
431   DALI_TEST_CHECK(fontList.size() > 0);
432
433   const PointSize26Dot6 pointSize = fontClient.GetPointSize(fontList.size());
434   DALI_TEST_EQUALS(pointSize, FontClient::DEFAULT_POINT_SIZE, TEST_LOCATION);
435
436   END_TEST;
437 }
438
439 std::ostream& operator<<(std::ostream& o, const FontDescription& description)
440 {
441   o << "Font path: " << description.path << " family: "
442     << " width : " << description.width << " weight : " << description.weight << " slant : " << description.slant << std::endl;
443   return o;
444 }
445
446 int UtcDaliFontClientGetDefaultPlatformFontDescription(void)
447 {
448   TestApplication application;
449   tet_infoline(" UtcDaliFontClientGetDefaultPlatformFontDescription");
450
451   FontClient fontClient;
452   fontClient = FontClient::Get();
453
454   FontDescription fontDescription;
455   fontClient.GetDefaultPlatformFontDescription(fontDescription);
456
457   std::ostringstream oss;
458   oss << fontDescription;
459   tet_printf("%s", oss.str().c_str());
460
461   DALI_TEST_CHECK(fontDescription.path.empty() == false);
462
463   FontId fontId = fontClient.FindFallbackFont('A',
464                                               fontDescription,
465                                               FontClient::DEFAULT_POINT_SIZE,
466                                               true);
467
468   bool supported = fontClient.IsCharacterSupportedByFont(fontId, 'A');
469   DALI_TEST_EQUALS(supported, true, TEST_LOCATION);
470   END_TEST;
471 }
472
473 namespace
474 {
475 constexpr uint8_t U1               = 1u;
476 constexpr uint8_t U2               = 2u;
477 constexpr uint8_t U3               = 3u;
478 constexpr uint8_t U4               = 4u;
479 constexpr uint8_t U5               = 5u;
480 constexpr uint8_t U6               = 6u;
481 constexpr uint8_t U0               = 0u;
482 constexpr uint8_t UTF8_LENGTH[256] = {
483   U1, U1, U1, U1, U1, U1, U1, U1, U1, U1, //
484   U1,
485   U1,
486   U1,
487   U1,
488   U1,
489   U1,
490   U1,
491   U1,
492   U1,
493   U1, //
494   U1,
495   U1,
496   U1,
497   U1,
498   U1,
499   U1,
500   U1,
501   U1,
502   U1,
503   U1, //
504   U1,
505   U1,
506   U1,
507   U1,
508   U1,
509   U1,
510   U1,
511   U1,
512   U1,
513   U1, //
514   U1,
515   U1,
516   U1,
517   U1,
518   U1,
519   U1,
520   U1,
521   U1,
522   U1,
523   U1, //
524   U1,
525   U1,
526   U1,
527   U1,
528   U1,
529   U1,
530   U1,
531   U1,
532   U1,
533   U1, //
534   U1,
535   U1,
536   U1,
537   U1,
538   U1,
539   U1,
540   U1,
541   U1,
542   U1,
543   U1, //
544   U1,
545   U1,
546   U1,
547   U1,
548   U1,
549   U1,
550   U1,
551   U1,
552   U1,
553   U1, //
554   U1,
555   U1,
556   U1,
557   U1,
558   U1,
559   U1,
560   U1,
561   U1,
562   U1,
563   U1, // lead byte = 0xxx xxxx (U+0000 - U+007F + some extended ascii characters)
564   U1,
565   U1,
566   U1,
567   U1,
568   U1,
569   U1,
570   U1,
571   U1,
572   U1,
573   U1, //
574   U1,
575   U1,
576   U1,
577   U1,
578   U1,
579   U1,
580   U1,
581   U1,
582   U1,
583   U1, //
584   U1,
585   U1,
586   U1,
587   U1,
588   U1,
589   U1,
590   U1,
591   U1,
592   U1,
593   U1, //
594   U1,
595   U1,
596   U1,
597   U1,
598   U1,
599   U1,
600   U1,
601   U1,
602   U1,
603   U1, //
604   U1,
605   U1,
606   U1,
607   U1,
608   U1,
609   U1,
610   U1,
611   U1,
612   U1,
613   U1, //
614   U1,
615   U1,
616   U1,
617   U1,
618   U1,
619   U1,
620   U1,
621   U1,
622   U1,
623   U1, //
624   U1,
625   U1,
626   U1,
627   U1,
628   U1,
629   U1,
630   U1,
631   U1,
632   U1,
633   U1, //
634   U1,
635   U1,
636   U1,
637   U1,
638   U1,
639   U1,
640   U1,
641   U1,
642   U1,
643   U1, //
644   U1,
645   U1,
646   U1,
647   U1,
648   U1,
649   U1,
650   U1,
651   U1,
652   U1,
653   U1, //
654   U1,
655   U1,
656   U1,
657   U1,
658   U1,
659   U1,
660   U1,
661   U1,
662   U1,
663   U1, //
664   U1,
665   U1, //
666
667   U2,
668   U2,
669   U2,
670   U2,
671   U2,
672   U2,
673   U2,
674   U2,
675   U2,
676   U2, //
677   U2,
678   U2,
679   U2,
680   U2,
681   U2,
682   U2,
683   U2,
684   U2,
685   U2,
686   U2, // lead byte = 110x xxxx (U+0080 - U+07FF)
687   U2,
688   U2,
689   U2,
690   U2,
691   U2,
692   U2,
693   U2,
694   U2,
695   U2,
696   U2, //
697   U2,
698   U2, //
699
700   U3,
701   U3,
702   U3,
703   U3,
704   U3,
705   U3,
706   U3,
707   U3,
708   U3,
709   U3, // lead byte = 1110 xxxx (U+0800 - U+FFFF)
710   U3,
711   U3,
712   U3,
713   U3,
714   U3,
715   U3, //
716
717   U4,
718   U4,
719   U4,
720   U4,
721   U4,
722   U4,
723   U4,
724   U4, // lead byte = 1111 0xxx (U+10000 - U+1FFFFF)
725
726   U5,
727   U5,
728   U5,
729   U5, // lead byte = 1111 10xx (U+200000 - U+3FFFFFF)
730
731   U6,
732   U6, // lead byte = 1111 110x (U+4000000 - U+7FFFFFFF)
733
734   U0,
735   U0, // Non valid.
736 };
737
738 constexpr uint8_t CR = 0xd;
739 constexpr uint8_t LF = 0xa;
740
741 uint8_t GetUtf8Length(uint8_t utf8LeadByte)
742 {
743   return UTF8_LENGTH[utf8LeadByte];
744 }
745
746 uint32_t Utf8ToUtf32(const uint8_t* const utf8, uint32_t length, uint32_t* utf32)
747 {
748   uint32_t numberOfCharacters = 0u;
749
750   const uint8_t* begin = utf8;
751   const uint8_t* end   = utf8 + length;
752
753   for(; begin < end; ++numberOfCharacters)
754   {
755     const uint8_t leadByte = *begin;
756
757     switch(UTF8_LENGTH[leadByte])
758     {
759       case U1:
760       {
761         if(CR == leadByte)
762         {
763           // Replace CR+LF or CR by LF
764           *utf32++ = LF;
765
766           // Look ahead if the next one is a LF.
767           ++begin;
768           if(begin < end)
769           {
770             if(LF == *begin)
771             {
772               ++begin;
773             }
774           }
775         }
776         else
777         {
778           *utf32++ = leadByte;
779           begin++;
780         }
781         break;
782       }
783
784       case U2:
785       {
786         uint32_t& code = *utf32++;
787         code           = leadByte & 0x1fu;
788         begin++;
789         code <<= 6u;
790         code |= *begin++ & 0x3fu;
791         break;
792       }
793
794       case U3:
795       {
796         uint32_t& code = *utf32++;
797         code           = leadByte & 0x0fu;
798         begin++;
799         code <<= 6u;
800         code |= *begin++ & 0x3fu;
801         code <<= 6u;
802         code |= *begin++ & 0x3fu;
803         break;
804       }
805
806       case U4:
807       {
808         uint32_t& code = *utf32++;
809         code           = leadByte & 0x07u;
810         begin++;
811         code <<= 6u;
812         code |= *begin++ & 0x3fu;
813         code <<= 6u;
814         code |= *begin++ & 0x3fu;
815         code <<= 6u;
816         code |= *begin++ & 0x3fu;
817         break;
818       }
819
820       case U5:
821       {
822         uint32_t& code = *utf32++;
823         code           = leadByte & 0x03u;
824         begin++;
825         code <<= 6u;
826         code |= *begin++ & 0x3fu;
827         code <<= 6u;
828         code |= *begin++ & 0x3fu;
829         code <<= 6u;
830         code |= *begin++ & 0x3fu;
831         code <<= 6u;
832         code |= *begin++ & 0x3fu;
833         break;
834       }
835
836       case U6:
837       {
838         uint32_t& code = *utf32++;
839         code           = leadByte & 0x01u;
840         begin++;
841         code <<= 6u;
842         code |= *begin++ & 0x3fu;
843         code <<= 6u;
844         code |= *begin++ & 0x3fu;
845         code <<= 6u;
846         code |= *begin++ & 0x3fu;
847         code <<= 6u;
848         code |= *begin++ & 0x3fu;
849         code <<= 6u;
850         code |= *begin++ & 0x3fu;
851         break;
852       }
853
854       case U0: // Invalid case
855       {
856         begin++;
857         *utf32++ = 0x20; // Use white space
858         break;
859       }
860     }
861   }
862
863   return numberOfCharacters;
864 }
865
866 TextAbstraction::FontId SetupBitmapFont()
867 {
868   struct GlyphDesc
869   {
870     GlyphDesc()
871     {
872     }
873     GlyphDesc(const std::string& url, const std::string& utf8)
874     {
875       this->url = url;
876
877       DALI_ASSERT_ALWAYS(utf8.size() <= 6u);
878
879 #pragma GCC diagnostic push
880 #pragma GCC diagnostic ignored "-Wstringop-overflow"
881       std::copy(utf8.begin(), utf8.end(), this->utf8);
882 #pragma GCC diagnostic pop
883     }
884     std::string url;
885     uint8_t     utf8[6];
886   };
887   std::vector<GlyphDesc> glyphs;
888
889   glyphs.push_back({TEST_RESOURCE_DIR "/fonts/bitmap/u0030.png", ":"});
890   glyphs.push_back({TEST_RESOURCE_DIR "/fonts/bitmap/u0031.png", "0"});
891   glyphs.push_back({TEST_RESOURCE_DIR "/fonts/bitmap/u0032.png", "1"});
892   glyphs.push_back({TEST_RESOURCE_DIR "/fonts/bitmap/u0033.png", "2"});
893   glyphs.push_back({TEST_RESOURCE_DIR "/fonts/bitmap/u0034.png", "3"});
894   glyphs.push_back({TEST_RESOURCE_DIR "/fonts/bitmap/u0035.png", "4"});
895   glyphs.push_back({TEST_RESOURCE_DIR "/fonts/bitmap/u0036.png", "5"});
896   glyphs.push_back({TEST_RESOURCE_DIR "/fonts/bitmap/u0037.png", "6"});
897   glyphs.push_back({TEST_RESOURCE_DIR "/fonts/bitmap/u0038.png", "7"});
898   glyphs.push_back({TEST_RESOURCE_DIR "/fonts/bitmap/u0039.png", "8"});
899   glyphs.push_back({TEST_RESOURCE_DIR "/fonts/bitmap/u003a.png", "9"});
900
901   TextAbstraction::BitmapFont bitmapFont;
902   bitmapFont.glyphs.reserve(glyphs.size());
903   bitmapFont.name               = "Digits";
904   bitmapFont.underlinePosition  = 0.f;
905   bitmapFont.underlineThickness = 0.f;
906   bitmapFont.isColorFont        = true;
907
908   for(const auto& glyph : glyphs)
909   {
910     uint32_t c = 0u;
911     Utf8ToUtf32(glyph.utf8, GetUtf8Length(glyph.utf8[0u]), &c);
912     TextAbstraction::BitmapGlyph bitmapGlyph(glyph.url, c, 34.f, 0.f);
913     bitmapFont.glyphs.push_back(std::move(bitmapGlyph));
914   }
915
916   TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
917   return fontClient.GetFontId(bitmapFont);
918 }
919
920 } // namespace
921
922 int UtcDaliFontClientTestBitmapFont(void)
923 {
924   TestApplication application;
925   tet_infoline(" UtcDaliFontClientTestBitmapFont");
926
927   FontClient fontClient;
928   fontClient = FontClient::Get();
929
930   auto bitmapFontId = SetupBitmapFont();
931
932   FontDescription fontDescription;
933   fontClient.GetDescription(bitmapFontId, fontDescription);
934   std::ostringstream oss;
935   oss << fontDescription;
936   tet_printf("Found: %d: %s", bitmapFontId, oss.str().c_str());
937
938   bool color = fontClient.IsColorGlyph(bitmapFontId, fontClient.GetGlyphIndex(bitmapFontId, '2'));
939   DALI_TEST_EQUALS(color, true, TEST_LOCATION);
940
941   DALI_TEST_EQUALS(fontClient.GetPointSize(bitmapFontId), FontClient::DEFAULT_POINT_SIZE, TEST_LOCATION);
942
943   DALI_TEST_EQUALS(fontClient.IsCharacterSupportedByFont(bitmapFontId, '3'), true, TEST_LOCATION);
944   DALI_TEST_EQUALS(fontClient.IsCharacterSupportedByFont(bitmapFontId, 'a'), false, TEST_LOCATION);
945
946   END_TEST;
947 }