Create glyph bitmap without copy if single color
[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 UtcDaliFontClientAtlasLimitation(void)
94 {
95   TestApplication             application;
96   bool                        result     = 0;
97   TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
98
99   tet_infoline("UtcDaliFontClientAtlasLimitation Default");
100   result = fontClient.IsAtlasLimitationEnabled();
101   DALI_TEST_EQUALS(TextAbstraction::FontClient::DEFAULT_ATLAS_LIMITATION_ENABLED, result, TEST_LOCATION);
102
103   tet_infoline("UtcDaliFontClientAtlasLimitation Enabled");
104   fontClient.EnableAtlasLimitation(true);
105   result = fontClient.IsAtlasLimitationEnabled();
106   DALI_TEST_EQUALS(true, result, TEST_LOCATION);
107
108   tet_infoline("UtcDaliFontClientAtlasLimitation Disabled");
109   fontClient.EnableAtlasLimitation(false);
110   result = fontClient.IsAtlasLimitationEnabled();
111   DALI_TEST_EQUALS(false, result, TEST_LOCATION);
112   END_TEST;
113 }
114
115 const std::string DEFAULT_FONT_DIR("/resources/fonts");
116 const uint32_t    MAX_WIDTH_FIT_IN_ATLAS  = TextAbstraction::FontClient::MAX_TEXT_ATLAS_WIDTH - TextAbstraction::FontClient::PADDING_TEXT_ATLAS_BLOCK;
117 const uint32_t    MAX_HEIGHT_FIT_IN_ATLAS = TextAbstraction::FontClient::MAX_TEXT_ATLAS_HEIGHT - TextAbstraction::FontClient::PADDING_TEXT_ATLAS_BLOCK;
118
119 int UtcDaliFontClientAtlasLimitationEnabled(void)
120 {
121   TestApplication application;
122
123   char*             pathNamePtr = get_current_dir_name();
124   const std::string pathName(pathNamePtr);
125   free(pathNamePtr);
126
127   TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
128   fontClient.EnableAtlasLimitation(true);
129
130   // The font file "DejaVuSans.ttf" is copied from Toolkit to Adaptor to make test-case of specific font-family.
131   // Note the block size depends on font-family.
132   // This is to create FontDescription and pass it to GetFontId with point-size (various cases).
133   TextAbstraction::FontDescription fontDescription;
134   fontDescription.path   = pathName + DEFAULT_FONT_DIR + "/dejavu/DejaVuSans.ttf";
135   fontDescription.family = "DejaVuSans";
136   fontDescription.width  = TextAbstraction::FontWidth::NONE;
137   fontDescription.weight = TextAbstraction::FontWeight::NORMAL;
138   fontDescription.slant  = TextAbstraction::FontSlant::NONE;
139
140   // Block's width or height are less than 512
141   tet_infoline("UtcDaliFontClientAtlasLimitationEnabled PointSize=200");
142   uint32_t                                     pointSize200 = 200 * TextAbstraction::FontClient::NUMBER_OF_POINTS_PER_ONE_UNIT_OF_POINT_SIZE;
143   TextAbstraction::FontId                      fontId200    = fontClient.GetFontId(fontDescription, pointSize200);
144   TextAbstraction::FontClient::GlyphBufferData glyphBufferData200;
145   glyphBufferData200.width  = 0;
146   glyphBufferData200.height = 0;
147   fontClient.CreateBitmap(fontId200, 68, false, false, glyphBufferData200, 0);
148
149   DALI_TEST_GREATER(MAX_WIDTH_FIT_IN_ATLAS, glyphBufferData200.width, TEST_LOCATION);
150   DALI_TEST_GREATER(MAX_HEIGHT_FIT_IN_ATLAS, glyphBufferData200.height, TEST_LOCATION);
151
152   // Block's width or height are  greater than 512 and less than 1024
153   uint32_t pointSize1000 = 1000 * TextAbstraction::FontClient::NUMBER_OF_POINTS_PER_ONE_UNIT_OF_POINT_SIZE;
154   tet_infoline("UtcDaliFontClientAtlasLimitationEnabled PointSize=1000");
155   TextAbstraction::FontId                      fontId1000 = fontClient.GetFontId(fontDescription, pointSize1000);
156   TextAbstraction::FontClient::GlyphBufferData glyphBufferData1000;
157   glyphBufferData1000.width  = 0;
158   glyphBufferData1000.height = 0;
159   fontClient.CreateBitmap(fontId1000, 68, false, false, glyphBufferData1000, 0);
160
161   DALI_TEST_GREATER(MAX_WIDTH_FIT_IN_ATLAS, glyphBufferData1000.width, TEST_LOCATION);
162   DALI_TEST_GREATER(MAX_HEIGHT_FIT_IN_ATLAS, glyphBufferData1000.height, TEST_LOCATION);
163
164   // Block's width or height are greater than 1024 and less than 2048
165   uint32_t pointSize2000 = 2000 * TextAbstraction::FontClient::NUMBER_OF_POINTS_PER_ONE_UNIT_OF_POINT_SIZE;
166   tet_infoline("UtcDaliFontClientAtlasLimitationEnabled PointSize=2000");
167   TextAbstraction::FontId                      fontId2000 = fontClient.GetFontId(fontDescription, pointSize2000);
168   TextAbstraction::FontClient::GlyphBufferData glyphBufferData2000;
169   glyphBufferData2000.width  = 0;
170   glyphBufferData2000.height = 0;
171   fontClient.CreateBitmap(fontId2000, 68, false, false, glyphBufferData2000, 0);
172
173   DALI_TEST_GREATER(MAX_WIDTH_FIT_IN_ATLAS, glyphBufferData2000.width, TEST_LOCATION);
174   DALI_TEST_GREATER(MAX_HEIGHT_FIT_IN_ATLAS, glyphBufferData2000.height, TEST_LOCATION);
175
176   // Release copied memories
177   free(glyphBufferData200.buffer);
178   free(glyphBufferData1000.buffer);
179   free(glyphBufferData2000.buffer);
180
181   END_TEST;
182 }
183
184 int UtcDaliFontClientAtlasLimitationDisabled(void)
185 {
186   TestApplication application;
187
188   char*             pathNamePtr = get_current_dir_name();
189   const std::string pathName(pathNamePtr);
190   free(pathNamePtr);
191
192   TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
193   fontClient.EnableAtlasLimitation(false);
194
195   TextAbstraction::FontDescription fontDescription;
196   fontDescription.path   = pathName + DEFAULT_FONT_DIR + "/dejavu/DejaVuSans.ttf";
197   fontDescription.family = "DejaVuSans";
198   fontDescription.width  = TextAbstraction::FontWidth::NONE;
199   fontDescription.weight = TextAbstraction::FontWeight::NORMAL;
200   fontDescription.slant  = TextAbstraction::FontSlant::NONE;
201
202   // Block's width or height are less than 512
203   tet_infoline("UtcDaliFontClientAtlasLimitationDisabled PointSize=200");
204   uint32_t                                     pointSize200 = 200 * TextAbstraction::FontClient::NUMBER_OF_POINTS_PER_ONE_UNIT_OF_POINT_SIZE;
205   TextAbstraction::FontId                      fontId200    = fontClient.GetFontId(fontDescription, pointSize200);
206   TextAbstraction::FontClient::GlyphBufferData glyphBufferData200;
207   glyphBufferData200.width  = 0;
208   glyphBufferData200.height = 0;
209   fontClient.CreateBitmap(fontId200, 68, false, false, glyphBufferData200, 0);
210
211   DALI_TEST_GREATER(512u, glyphBufferData200.width, TEST_LOCATION);  //93u
212   DALI_TEST_GREATER(512u, glyphBufferData200.height, TEST_LOCATION); //115u
213
214   // Block's width or height are  greater than 512 and less than 1024
215   tet_infoline("UtcDaliFontClientAtlasLimitationDisabled PointSize=1000");
216   uint32_t                                     pointSize1000 = 1000 * TextAbstraction::FontClient::NUMBER_OF_POINTS_PER_ONE_UNIT_OF_POINT_SIZE;
217   TextAbstraction::FontId                      fontId1000    = fontClient.GetFontId(fontDescription, pointSize1000);
218   TextAbstraction::FontClient::GlyphBufferData glyphBufferData1000;
219   glyphBufferData1000.width  = 0;
220   glyphBufferData1000.height = 0;
221   fontClient.CreateBitmap(fontId1000, 68, false, false, glyphBufferData1000, 0);
222
223   DALI_TEST_GREATER(512u, glyphBufferData1000.width, TEST_LOCATION);  //462u
224   DALI_TEST_GREATER(glyphBufferData1000.height, 512u, TEST_LOCATION); //574u
225
226   // Block's width or height are greater than 1024 and less than 2048
227   tet_infoline("UtcDaliFontClientAtlasLimitationDisabled PointSize=2000");
228   uint32_t                                     pointSize2000 = 2000 * TextAbstraction::FontClient::NUMBER_OF_POINTS_PER_ONE_UNIT_OF_POINT_SIZE;
229   TextAbstraction::FontId                      fontId2000    = fontClient.GetFontId(fontDescription, pointSize2000);
230   TextAbstraction::FontClient::GlyphBufferData glyphBufferData2000;
231   glyphBufferData2000.width  = 0;
232   glyphBufferData2000.height = 0;
233   fontClient.CreateBitmap(fontId2000, 68, false, false, glyphBufferData2000, 0);
234
235   DALI_TEST_GREATER(1024u, glyphBufferData2000.width, TEST_LOCATION);  //924u
236   DALI_TEST_GREATER(glyphBufferData2000.height, 1024u, TEST_LOCATION); //1148u
237
238   END_TEST;
239 }
240
241 int UtcDaliFontClientCurrentMaximumBlockSizeFitInAtlas(void)
242 {
243   TestApplication application;
244   tet_infoline(" UtcDaliFontClientCurrentMaximumBlockSizeFitInAtlas ");
245
246   bool                        isChanged;
247   TextAbstraction::FontClient fontClient;
248   fontClient = TextAbstraction::FontClient::Get();
249
250   Size defaultTextAtlasSize              = fontClient.GetDefaultTextAtlasSize();
251   Size maximumTextAtlasSize              = fontClient.GetMaximumTextAtlasSize();
252   Size currentMaximumBlockSizeFitInAtlas = fontClient.GetCurrentMaximumBlockSizeFitInAtlas();
253
254   tet_infoline("CurrentMaximumBlockSizeFitInAtlas start with default ");
255   DALI_TEST_EQUALS(currentMaximumBlockSizeFitInAtlas, defaultTextAtlasSize, TEST_LOCATION);
256
257   tet_infoline("SetCurrentMaximumBlockSizeFitInAtlas is changed with current ");
258   isChanged = fontClient.SetCurrentMaximumBlockSizeFitInAtlas(currentMaximumBlockSizeFitInAtlas);
259   DALI_TEST_CHECK(isChanged);
260
261   Size decreaseOnlyWidth(currentMaximumBlockSizeFitInAtlas.width - 1u, currentMaximumBlockSizeFitInAtlas.height);
262   tet_infoline("SetCurrentMaximumBlockSizeFitInAtlas is changed with width < current ");
263   isChanged = fontClient.SetCurrentMaximumBlockSizeFitInAtlas(decreaseOnlyWidth);
264   DALI_TEST_CHECK(isChanged);
265
266   Size decreaseOnlyHeigth(currentMaximumBlockSizeFitInAtlas.width, currentMaximumBlockSizeFitInAtlas.height - 1u);
267   tet_infoline("SetCurrentMaximumBlockSizeFitInAtlas is changed with height < current ");
268   isChanged = fontClient.SetCurrentMaximumBlockSizeFitInAtlas(decreaseOnlyHeigth);
269   DALI_TEST_CHECK(isChanged);
270
271   Size decreaseBoth(currentMaximumBlockSizeFitInAtlas.width - 1u, currentMaximumBlockSizeFitInAtlas.height - 1u);
272   tet_infoline("SetCurrentMaximumBlockSizeFitInAtlas is changed with size < current ");
273   isChanged = fontClient.SetCurrentMaximumBlockSizeFitInAtlas(decreaseBoth);
274   DALI_TEST_CHECK(isChanged);
275
276   Size increaseOnlyWidth(maximumTextAtlasSize.width + 1u, currentMaximumBlockSizeFitInAtlas.height);
277   tet_infoline("SetCurrentMaximumBlockSizeFitInAtlas is not changed with width > max ");
278   isChanged = fontClient.SetCurrentMaximumBlockSizeFitInAtlas(increaseOnlyWidth);
279   DALI_TEST_CHECK(!isChanged);
280
281   Size increaseOnlyHeigth(currentMaximumBlockSizeFitInAtlas.width, maximumTextAtlasSize.height + 1u);
282   tet_infoline("SetCurrentMaximumBlockSizeFitInAtlas is not changed with height > max ");
283   isChanged = fontClient.SetCurrentMaximumBlockSizeFitInAtlas(increaseOnlyHeigth);
284   DALI_TEST_CHECK(!isChanged);
285
286   Size increaseBoth(maximumTextAtlasSize.width + 1u, maximumTextAtlasSize.height + 1u);
287   tet_infoline("SetCurrentMaximumBlockSizeFitInAtlas is not changed with size > max ");
288   isChanged = fontClient.SetCurrentMaximumBlockSizeFitInAtlas(increaseBoth);
289   DALI_TEST_CHECK(!isChanged);
290
291   currentMaximumBlockSizeFitInAtlas = fontClient.GetCurrentMaximumBlockSizeFitInAtlas();
292   if(currentMaximumBlockSizeFitInAtlas.width < maximumTextAtlasSize.width && currentMaximumBlockSizeFitInAtlas.height < maximumTextAtlasSize.height)
293   {
294     tet_infoline("SetCurrentMaximumBlockSizeFitInAtlas is changed with current < size < max ");
295     Size increaseWidth = Size(currentMaximumBlockSizeFitInAtlas.width + 1u, currentMaximumBlockSizeFitInAtlas.height);
296     isChanged          = fontClient.SetCurrentMaximumBlockSizeFitInAtlas(increaseWidth);
297     DALI_TEST_CHECK(isChanged);
298     currentMaximumBlockSizeFitInAtlas = fontClient.GetCurrentMaximumBlockSizeFitInAtlas();
299
300     Size increaseHeigth = Size(currentMaximumBlockSizeFitInAtlas.width, currentMaximumBlockSizeFitInAtlas.height + 1u);
301     isChanged           = fontClient.SetCurrentMaximumBlockSizeFitInAtlas(increaseHeigth);
302     DALI_TEST_CHECK(isChanged);
303     currentMaximumBlockSizeFitInAtlas = fontClient.GetCurrentMaximumBlockSizeFitInAtlas();
304
305     Size sizeLessThanMax = Size(currentMaximumBlockSizeFitInAtlas.width + 1u, currentMaximumBlockSizeFitInAtlas.height + 1u);
306     isChanged            = fontClient.SetCurrentMaximumBlockSizeFitInAtlas(sizeLessThanMax);
307
308     if(currentMaximumBlockSizeFitInAtlas.width < maximumTextAtlasSize.width && currentMaximumBlockSizeFitInAtlas.height < maximumTextAtlasSize.height)
309     {
310       DALI_TEST_CHECK(isChanged);
311     }
312     else
313     {
314       DALI_TEST_CHECK(!isChanged);
315     }
316
317     currentMaximumBlockSizeFitInAtlas = fontClient.GetCurrentMaximumBlockSizeFitInAtlas();
318
319     DALI_TEST_NOT_EQUALS(currentMaximumBlockSizeFitInAtlas, defaultTextAtlasSize, 0.0f, TEST_LOCATION);
320     DALI_TEST_EQUALS(currentMaximumBlockSizeFitInAtlas, sizeLessThanMax, TEST_LOCATION);
321
322     tet_infoline("SetCurrentMaximumBlockSizeFitInAtlas is not changed with size == max ");
323     isChanged = fontClient.SetCurrentMaximumBlockSizeFitInAtlas(maximumTextAtlasSize);
324     DALI_TEST_CHECK(!isChanged);
325   }
326
327   currentMaximumBlockSizeFitInAtlas = fontClient.GetCurrentMaximumBlockSizeFitInAtlas();
328   DALI_TEST_NOT_EQUALS(currentMaximumBlockSizeFitInAtlas, maximumTextAtlasSize, 0.0f, TEST_LOCATION);
329
330   END_TEST;
331 }
332
333 int UtcDaliFontClientTextAtlasConstants(void)
334 {
335   TestApplication application;
336   tet_infoline(" UtcDaliFontClientTextAtlasConstants ");
337
338   TextAbstraction::FontClient fontClient;
339   fontClient = TextAbstraction::FontClient::Get();
340
341   Size defaultTextAtlasSize = fontClient.GetDefaultTextAtlasSize();
342   Size defaultTextAtlasWidthHeight(TextAbstraction::FontClient::DEFAULT_TEXT_ATLAS_WIDTH, TextAbstraction::FontClient::DEFAULT_TEXT_ATLAS_HEIGHT);
343   DALI_TEST_EQUALS(defaultTextAtlasSize, TextAbstraction::FontClient::DEFAULT_TEXT_ATLAS_SIZE, TEST_LOCATION);
344   DALI_TEST_EQUALS(defaultTextAtlasSize, defaultTextAtlasWidthHeight, TEST_LOCATION);
345
346   Size maximumTextAtlasSize = fontClient.GetMaximumTextAtlasSize();
347   Size maxTextAtlasWidthHeight(TextAbstraction::FontClient::MAX_TEXT_ATLAS_WIDTH, TextAbstraction::FontClient::MAX_TEXT_ATLAS_HEIGHT);
348   DALI_TEST_EQUALS(maximumTextAtlasSize, TextAbstraction::FontClient::MAX_TEXT_ATLAS_SIZE, TEST_LOCATION);
349   DALI_TEST_EQUALS(maximumTextAtlasSize, maxTextAtlasWidthHeight, TEST_LOCATION);
350
351   uint32_t numberOfPointsPerOneUnitOfPointSize = fontClient.GetNumberOfPointsPerOneUnitOfPointSize();
352   DALI_TEST_EQUALS(numberOfPointsPerOneUnitOfPointSize, TextAbstraction::FontClient::NUMBER_OF_POINTS_PER_ONE_UNIT_OF_POINT_SIZE, TEST_LOCATION);
353
354   END_TEST;
355 }
356
357 using namespace Dali::TextAbstraction;
358
359 int UtcDaliFontClientGetDefaultFonts(void)
360 {
361   TestApplication application;
362   tet_infoline(" UtcDaliFontClientGetDefaultFonts ");
363
364   FontClient fontClient;
365   fontClient = FontClient::Get();
366
367   FontList fontList;
368   fontClient.GetDefaultFonts(fontList);
369
370   std::ostringstream oss;
371   oss << fontList << std::endl;
372
373   tet_printf("FontList: %s", oss.str().c_str());
374   DALI_TEST_CHECK(fontList.size() > 0);
375
376   END_TEST;
377 }
378
379 int UtcDaliFontClientGetSystemFonts(void)
380 {
381   TestApplication application;
382   tet_infoline(" UtcDaliFontClientGetSystemFonts ");
383
384   FontClient fontClient;
385   fontClient = FontClient::Get();
386
387   FontList fontList;
388   fontClient.GetSystemFonts(fontList);
389
390   std::ostringstream oss;
391   oss << fontList << std::endl;
392
393   tet_printf("FontList: %s", oss.str().c_str());
394   DALI_TEST_CHECK(fontList.size() > 0);
395
396   const PointSize26Dot6 pointSize = fontClient.GetPointSize(fontList.size());
397   DALI_TEST_EQUALS(pointSize, FontClient::DEFAULT_POINT_SIZE, TEST_LOCATION);
398
399   END_TEST;
400 }
401
402 std::ostream& operator<<(std::ostream& o, const FontDescription& description)
403 {
404   o << "Font path: " << description.path << " family: "
405     << " width : " << description.width << " weight : " << description.weight << " slant : " << description.slant << std::endl;
406   return o;
407 }
408
409 int UtcDaliFontClientGetDefaultPlatformFontDescription(void)
410 {
411   TestApplication application;
412   tet_infoline(" UtcDaliFontClientGetDefaultPlatformFontDescription");
413
414   FontClient fontClient;
415   fontClient = FontClient::Get();
416
417   FontDescription fontDescription;
418   fontClient.GetDefaultPlatformFontDescription(fontDescription);
419
420   std::ostringstream oss;
421   oss << fontDescription;
422   tet_printf("%s", oss.str().c_str());
423
424   DALI_TEST_CHECK(fontDescription.path.empty() == false);
425
426   FontId fontId = fontClient.FindFallbackFont('A',
427                                               fontDescription,
428                                               FontClient::DEFAULT_POINT_SIZE,
429                                               true);
430
431   bool supported = fontClient.IsCharacterSupportedByFont(fontId, 'A');
432   DALI_TEST_EQUALS(supported, true, TEST_LOCATION);
433   END_TEST;
434 }
435
436 namespace
437 {
438 constexpr uint8_t U1               = 1u;
439 constexpr uint8_t U2               = 2u;
440 constexpr uint8_t U3               = 3u;
441 constexpr uint8_t U4               = 4u;
442 constexpr uint8_t U5               = 5u;
443 constexpr uint8_t U6               = 6u;
444 constexpr uint8_t U0               = 0u;
445 constexpr uint8_t UTF8_LENGTH[256] = {
446   U1, U1, U1, U1, U1, U1, U1, U1, U1, U1, //
447   U1,
448   U1,
449   U1,
450   U1,
451   U1,
452   U1,
453   U1,
454   U1,
455   U1,
456   U1, //
457   U1,
458   U1,
459   U1,
460   U1,
461   U1,
462   U1,
463   U1,
464   U1,
465   U1,
466   U1, //
467   U1,
468   U1,
469   U1,
470   U1,
471   U1,
472   U1,
473   U1,
474   U1,
475   U1,
476   U1, //
477   U1,
478   U1,
479   U1,
480   U1,
481   U1,
482   U1,
483   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, // lead byte = 0xxx xxxx (U+0000 - U+007F + some extended ascii characters)
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,
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
630   U2,
631   U2,
632   U2,
633   U2,
634   U2,
635   U2,
636   U2,
637   U2,
638   U2,
639   U2, //
640   U2,
641   U2,
642   U2,
643   U2,
644   U2,
645   U2,
646   U2,
647   U2,
648   U2,
649   U2, // lead byte = 110x xxxx (U+0080 - U+07FF)
650   U2,
651   U2,
652   U2,
653   U2,
654   U2,
655   U2,
656   U2,
657   U2,
658   U2,
659   U2, //
660   U2,
661   U2, //
662
663   U3,
664   U3,
665   U3,
666   U3,
667   U3,
668   U3,
669   U3,
670   U3,
671   U3,
672   U3, // lead byte = 1110 xxxx (U+0800 - U+FFFF)
673   U3,
674   U3,
675   U3,
676   U3,
677   U3,
678   U3, //
679
680   U4,
681   U4,
682   U4,
683   U4,
684   U4,
685   U4,
686   U4,
687   U4, // lead byte = 1111 0xxx (U+10000 - U+1FFFFF)
688
689   U5,
690   U5,
691   U5,
692   U5, // lead byte = 1111 10xx (U+200000 - U+3FFFFFF)
693
694   U6,
695   U6, // lead byte = 1111 110x (U+4000000 - U+7FFFFFFF)
696
697   U0,
698   U0, // Non valid.
699 };
700
701 constexpr uint8_t CR = 0xd;
702 constexpr uint8_t LF = 0xa;
703
704 uint8_t GetUtf8Length(uint8_t utf8LeadByte)
705 {
706   return UTF8_LENGTH[utf8LeadByte];
707 }
708
709 uint32_t Utf8ToUtf32(const uint8_t* const utf8, uint32_t length, uint32_t* utf32)
710 {
711   uint32_t numberOfCharacters = 0u;
712
713   const uint8_t* begin = utf8;
714   const uint8_t* end   = utf8 + length;
715
716   for(; begin < end; ++numberOfCharacters)
717   {
718     const uint8_t leadByte = *begin;
719
720     switch(UTF8_LENGTH[leadByte])
721     {
722       case U1:
723       {
724         if(CR == leadByte)
725         {
726           // Replace CR+LF or CR by LF
727           *utf32++ = LF;
728
729           // Look ahead if the next one is a LF.
730           ++begin;
731           if(begin < end)
732           {
733             if(LF == *begin)
734             {
735               ++begin;
736             }
737           }
738         }
739         else
740         {
741           *utf32++ = leadByte;
742           begin++;
743         }
744         break;
745       }
746
747       case U2:
748       {
749         uint32_t& code = *utf32++;
750         code           = leadByte & 0x1fu;
751         begin++;
752         code <<= 6u;
753         code |= *begin++ & 0x3fu;
754         break;
755       }
756
757       case U3:
758       {
759         uint32_t& code = *utf32++;
760         code           = leadByte & 0x0fu;
761         begin++;
762         code <<= 6u;
763         code |= *begin++ & 0x3fu;
764         code <<= 6u;
765         code |= *begin++ & 0x3fu;
766         break;
767       }
768
769       case U4:
770       {
771         uint32_t& code = *utf32++;
772         code           = leadByte & 0x07u;
773         begin++;
774         code <<= 6u;
775         code |= *begin++ & 0x3fu;
776         code <<= 6u;
777         code |= *begin++ & 0x3fu;
778         code <<= 6u;
779         code |= *begin++ & 0x3fu;
780         break;
781       }
782
783       case U5:
784       {
785         uint32_t& code = *utf32++;
786         code           = leadByte & 0x03u;
787         begin++;
788         code <<= 6u;
789         code |= *begin++ & 0x3fu;
790         code <<= 6u;
791         code |= *begin++ & 0x3fu;
792         code <<= 6u;
793         code |= *begin++ & 0x3fu;
794         code <<= 6u;
795         code |= *begin++ & 0x3fu;
796         break;
797       }
798
799       case U6:
800       {
801         uint32_t& code = *utf32++;
802         code           = leadByte & 0x01u;
803         begin++;
804         code <<= 6u;
805         code |= *begin++ & 0x3fu;
806         code <<= 6u;
807         code |= *begin++ & 0x3fu;
808         code <<= 6u;
809         code |= *begin++ & 0x3fu;
810         code <<= 6u;
811         code |= *begin++ & 0x3fu;
812         code <<= 6u;
813         code |= *begin++ & 0x3fu;
814         break;
815       }
816
817       case U0: // Invalid case
818       {
819         begin++;
820         *utf32++ = 0x20; // Use white space
821         break;
822       }
823     }
824   }
825
826   return numberOfCharacters;
827 }
828
829 TextAbstraction::FontId SetupBitmapFont()
830 {
831   struct GlyphDesc
832   {
833     GlyphDesc()
834     {
835     }
836     GlyphDesc(const std::string& url, const std::string& utf8)
837     {
838       this->url = url;
839       std::copy(utf8.begin(), utf8.end(), this->utf8);
840     }
841     std::string url;
842     uint8_t     utf8[4];
843   };
844   std::vector<GlyphDesc> glyphs;
845
846   glyphs.push_back({TEST_RESOURCE_DIR "/fonts/bitmap/u0030.png", ":"});
847   glyphs.push_back({TEST_RESOURCE_DIR "/fonts/bitmap/u0031.png", "0"});
848   glyphs.push_back({TEST_RESOURCE_DIR "/fonts/bitmap/u0032.png", "1"});
849   glyphs.push_back({TEST_RESOURCE_DIR "/fonts/bitmap/u0033.png", "2"});
850   glyphs.push_back({TEST_RESOURCE_DIR "/fonts/bitmap/u0034.png", "3"});
851   glyphs.push_back({TEST_RESOURCE_DIR "/fonts/bitmap/u0035.png", "4"});
852   glyphs.push_back({TEST_RESOURCE_DIR "/fonts/bitmap/u0036.png", "5"});
853   glyphs.push_back({TEST_RESOURCE_DIR "/fonts/bitmap/u0037.png", "6"});
854   glyphs.push_back({TEST_RESOURCE_DIR "/fonts/bitmap/u0038.png", "7"});
855   glyphs.push_back({TEST_RESOURCE_DIR "/fonts/bitmap/u0039.png", "8"});
856   glyphs.push_back({TEST_RESOURCE_DIR "/fonts/bitmap/u003a.png", "9"});
857
858   TextAbstraction::BitmapFont bitmapFont;
859   bitmapFont.glyphs.reserve(glyphs.size());
860   bitmapFont.name               = "Digits";
861   bitmapFont.underlinePosition  = 0.f;
862   bitmapFont.underlineThickness = 0.f;
863   bitmapFont.isColorFont        = true;
864
865   for(const auto& glyph : glyphs)
866   {
867     uint32_t c = 0u;
868     Utf8ToUtf32(glyph.utf8, GetUtf8Length(glyph.utf8[0u]), &c);
869     TextAbstraction::BitmapGlyph bitmapGlyph(glyph.url, c, 34.f, 0.f);
870     bitmapFont.glyphs.push_back(std::move(bitmapGlyph));
871   }
872
873   TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
874   return fontClient.GetFontId(bitmapFont);
875 }
876
877 } // namespace
878
879 int UtcDaliFontClientTestBitmapFont(void)
880 {
881   TestApplication application;
882   tet_infoline(" UtcDaliFontClientTestBitmapFont");
883
884   FontClient fontClient;
885   fontClient = FontClient::Get();
886
887   auto bitmapFontId = SetupBitmapFont();
888
889   FontDescription fontDescription;
890   fontClient.GetDescription(bitmapFontId, fontDescription);
891   std::ostringstream oss;
892   oss << fontDescription;
893   tet_printf("Found: %d: %s", bitmapFontId, oss.str().c_str());
894
895   bool color = fontClient.IsColorGlyph(bitmapFontId, fontClient.GetGlyphIndex(bitmapFontId, '2'));
896   DALI_TEST_EQUALS(color, true, TEST_LOCATION);
897
898   DALI_TEST_EQUALS(fontClient.GetPointSize(bitmapFontId), FontClient::DEFAULT_POINT_SIZE, TEST_LOCATION);
899
900   DALI_TEST_EQUALS(fontClient.IsCharacterSupportedByFont(bitmapFontId, '3'), true, TEST_LOCATION);
901   DALI_TEST_EQUALS(fontClient.IsCharacterSupportedByFont(bitmapFontId, 'a'), false, TEST_LOCATION);
902
903   END_TEST;
904 }