Tizen 2.1 base
[framework/osp/uifw.git] / src / graphics / FGrp_FontFt2.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Flora License, Version 1.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://floralicense.org/license/
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an AS IS BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /*
19  * @file        FGrp_FontFt2.cpp
20  * @brief       This is the implementation file for _FontFt2 class.
21  *
22  */
23
24 #include <new>
25 #include <math.h>
26
27 #include <unique_ptr.h>
28
29 #include <ft2build.h>
30 #include FT_FREETYPE_H
31 #include FT_OUTLINE_H
32
33 #include <FBaseErrors.h>
34
35 #include <FBaseSysLog.h>
36 #include <FBaseUtilStringUtil.h>
37 #include <FBaseColIHashCodeProviderT.h>
38
39 #include "FGrp_FontFt2.h"
40 #include "FGrp_FontCache.h"
41 #include "util/FGrp_UtilTemplate.h"
42
43 #include <fribidi.h>
44 #include <hb.h>
45 #include <hb-ft.h>
46
47 #define CHECK_NULL_PARAM(data) if (data == null) \
48         { \
49                 return false; \
50         }
51 #define CONVERT_INTEGER_TO_26_6_FIXED_POINT(value) (value * 64)
52 #define CONVERT_26_6_FIXED_POINT_TO_INTEGER(value) (value / 64)
53
54 using namespace Tizen::Base;
55 using namespace Tizen::Base::Collection;
56
57 namespace // unnamed
58 {
59 const double _M_PI = 3.14159265358979323846;
60 const double _ITALIC_ANGLE = 10.619655;
61 const long _DEFAULT_FONT_SIZE = CONVERT_INTEGER_TO_26_6_FIXED_POINT(16); // 16 pixel size in 26.6 fixed point
62 const long _DEFAULT_RES = 72;
63 const long _FIXED_SHIFT = 10;       // in fixed point number, the number of assigned bit below point.
64 const unsigned long _INDEX_FIRST = 32;       // in first resource, the first chracter(space)
65 const unsigned long _INDEX_COUNT = 95;       // first resource character count
66
67 bool
68 _CompareFamilyForTitling(String& familyName)
69 {
70         String _compNames[] =
71         {
72                 L"TitlingGothicFB Comp",
73                 L"TitlingGothicFB Cond",
74                 L"TitlingGothicFB Narrow",
75                 L"TitlingGothicFB Skyline"
76         };
77
78         for (unsigned int i = 0; i < sizeof(_compNames) / sizeof(_compNames[0]); i++)
79         {
80                 if (familyName == _compNames[i])
81                 {
82                         return true;
83                 }
84         }
85
86         return false;
87 }
88
89 const hb_script_t _HarfbuzzScript[] =
90 {
91         HB_SCRIPT_COMMON,
92         HB_SCRIPT_INHERITED,
93         HB_SCRIPT_ARABIC,
94         HB_SCRIPT_ARMENIAN,
95         HB_SCRIPT_BENGALI,
96         HB_SCRIPT_BOPOMOFO,
97         HB_SCRIPT_CHEROKEE,
98         HB_SCRIPT_COPTIC,
99         HB_SCRIPT_CYRILLIC,
100         HB_SCRIPT_DESERET,
101         HB_SCRIPT_DEVANAGARI,
102         HB_SCRIPT_ETHIOPIC,
103         HB_SCRIPT_GEORGIAN,
104         HB_SCRIPT_GOTHIC,
105         HB_SCRIPT_GREEK,
106         HB_SCRIPT_GUJARATI,
107         HB_SCRIPT_GURMUKHI,
108         HB_SCRIPT_HAN,
109         HB_SCRIPT_HANGUL,
110         HB_SCRIPT_HEBREW,
111         HB_SCRIPT_HIRAGANA,
112         HB_SCRIPT_KANNADA,
113         HB_SCRIPT_KATAKANA,
114         HB_SCRIPT_KHMER,
115         HB_SCRIPT_LAO,
116         HB_SCRIPT_LATIN,
117         HB_SCRIPT_MALAYALAM,
118         HB_SCRIPT_MONGOLIAN,
119         HB_SCRIPT_MYANMAR,
120         HB_SCRIPT_OGHAM,
121         HB_SCRIPT_OLD_ITALIC,
122         HB_SCRIPT_ORIYA,
123         HB_SCRIPT_RUNIC,
124         HB_SCRIPT_SINHALA,
125         HB_SCRIPT_SYRIAC,
126         HB_SCRIPT_TAMIL,
127         HB_SCRIPT_TELUGU,
128         HB_SCRIPT_THAANA,
129         HB_SCRIPT_THAI,
130         HB_SCRIPT_TIBETAN,
131         HB_SCRIPT_CANADIAN_ABORIGINAL,
132         HB_SCRIPT_YI,
133         HB_SCRIPT_TAGALOG,
134         HB_SCRIPT_HANUNOO,
135         HB_SCRIPT_BUHID,
136         HB_SCRIPT_TAGBANWA,
137
138         /* Unicode-4.0 additions */
139         HB_SCRIPT_BRAILLE,
140         HB_SCRIPT_CYPRIOT,
141         HB_SCRIPT_LIMBU,
142         HB_SCRIPT_OSMANYA,
143         HB_SCRIPT_SHAVIAN,
144         HB_SCRIPT_LINEAR_B,
145         HB_SCRIPT_TAI_LE,
146         HB_SCRIPT_UGARITIC,
147
148         /* Unicode-4.1 additions */
149         HB_SCRIPT_NEW_TAI_LUE,
150         HB_SCRIPT_BUGINESE,
151         HB_SCRIPT_GLAGOLITIC,
152         HB_SCRIPT_TIFINAGH,
153         HB_SCRIPT_SYLOTI_NAGRI,
154         HB_SCRIPT_OLD_PERSIAN,
155         HB_SCRIPT_KHAROSHTHI,
156
157         /* Unicode-5.0 additions */
158         HB_SCRIPT_UNKNOWN,
159         HB_SCRIPT_BALINESE,
160         HB_SCRIPT_CUNEIFORM,
161         HB_SCRIPT_PHOENICIAN,
162         HB_SCRIPT_PHAGS_PA,
163         HB_SCRIPT_NKO,
164
165         /* Unicode-5.1 additions */
166         HB_SCRIPT_KAYAH_LI,
167         HB_SCRIPT_LEPCHA,
168         HB_SCRIPT_REJANG,
169         HB_SCRIPT_SUNDANESE,
170         HB_SCRIPT_SAURASHTRA,
171         HB_SCRIPT_CHAM,
172         HB_SCRIPT_OL_CHIKI,
173         HB_SCRIPT_VAI,
174         HB_SCRIPT_CARIAN,
175         HB_SCRIPT_LYCIAN,
176         HB_SCRIPT_LYDIAN,
177
178         /* Unicode-5.2 additions */
179         HB_SCRIPT_AVESTAN,
180         HB_SCRIPT_BAMUM,
181         HB_SCRIPT_EGYPTIAN_HIEROGLYPHS,
182         HB_SCRIPT_IMPERIAL_ARAMAIC,
183         HB_SCRIPT_INSCRIPTIONAL_PAHLAVI,
184         HB_SCRIPT_INSCRIPTIONAL_PARTHIAN,
185         HB_SCRIPT_JAVANESE,
186         HB_SCRIPT_KAITHI,
187         HB_SCRIPT_TAI_THAM,
188         HB_SCRIPT_LISU,
189         HB_SCRIPT_MEETEI_MAYEK,
190         HB_SCRIPT_OLD_SOUTH_ARABIAN,
191         HB_SCRIPT_OLD_TURKIC,
192         HB_SCRIPT_SAMARITAN,
193         HB_SCRIPT_TAI_VIET,
194
195         /* Unicode-6.0 additions */
196         HB_SCRIPT_BATAK,
197         HB_SCRIPT_BRAHMI,
198         HB_SCRIPT_MANDAIC
199 };
200
201 template<class T>
202 class _FontHashCodeProvider
203         : public IHashCodeProviderT <T>
204 {
205 public:
206         _FontHashCodeProvider(void)
207         {
208         }
209
210         virtual ~_FontHashCodeProvider(void)
211         {
212         }
213
214         virtual int GetHashCode(const T& obj) const
215         {
216                 return obj.GetHashCode();
217         }
218 };
219
220 template<class T>
221 class _FontComparer
222         : public IComparerT <T>
223 {
224 public:
225         _FontComparer(void)
226         {
227         }
228
229         virtual ~_FontComparer(void)
230         {
231         }
232
233         virtual result Compare(const T& obj1, const T& obj2, int& cmp) const
234         {
235                 String& objString1 = static_cast <String&>(const_cast <T&>(obj1));
236                 String& objString2 = static_cast <String&>(const_cast <T&>(obj2));
237
238                 cmp = objString1.CompareTo(objString2);
239
240                 return E_SUCCESS;
241         }
242 };
243
244 const _FontHashCodeProvider<String> _fontHashCodeProvider;
245 const _FontComparer<String> _fontComparer;
246
247 } // unnamed
248
249 namespace Tizen { namespace Graphics
250 {
251
252 inline bool
253 _IsEqual(float f1, float f2)
254 {
255         return (((f1 > f2) ? f1 - f2 : f2 - f1) < 0.00001f); // epsilon is assumed to be 0.0001, not 1.192092896e-07f
256 }
257
258 _FontFt2::_FontFt2()
259         : __isValid(false)
260         , __isLoadGlyph(false)
261         , __pFontEngine(null)
262         , __pFontFace(null)
263         , __pFontBuffer(null)
264         , __isStaticBuffer(false)
265 {
266         __fontAttrib.size = _DEFAULT_FONT_SIZE;
267         __fontAttrib.angle = 0.0f;
268         __fontAttrib.style = _IFont::STYLE_NONE;
269         __fontAttrib.quality = _IFont::QUALITY_HIGH;
270         __fontAttrib.xExpansion = 100;
271         __fontAttrib.boldWeight = 1 << 6; //5L<<14;
272
273         __fallbackFontMap.Construct(1, 0, _fontHashCodeProvider, _fontComparer);
274         //create cache
275
276         __fontCache.reset(new (std::nothrow) _FontCache());
277 }
278
279 _FontFt2::~_FontFt2()
280 {
281         if (!__isValid)
282         {
283                 return;
284         }
285
286         __CleanUp();
287         __isValid = false;
288
289         __fallbackFontMap.RemoveAll();
290 }
291
292 bool
293 _FontFt2::Create(const void* pBuffer, long bufSize, long face)
294 {
295         if (__isValid)
296         {
297                 return false;
298         }
299
300         int error = FT_Init_FreeType(static_cast<FT_Library*>((void*) &__pFontEngine));
301
302         if (error)
303         {
304                 __CleanUp();
305
306                 return false;
307         }
308
309         // should keep the buffer
310         __pFontBuffer = new (std::nothrow) byte[bufSize];
311
312         if (!__pFontBuffer)
313         {
314                 __CleanUp();
315
316                 return false;
317         }
318
319         memcpy(__pFontBuffer, pBuffer, bufSize);
320
321         error = FT_New_Memory_Face(FT_Library(__pFontEngine), (const byte*) __pFontBuffer, bufSize, face, static_cast<FT_Face*>((void*) &__pFontFace));
322
323         if (error)
324         {
325                 __CleanUp();
326
327                 return false;
328         }
329
330         FT_Face pFace = FT_Face(__pFontFace);
331
332         if ((pFace->charmap == null) && (pFace->num_charmaps > 0))
333         {
334                 FT_Set_Charmap(pFace, pFace->charmaps[0]);
335         }
336
337         __isValid = true;
338
339         return true;
340 }
341
342 bool
343 _FontFt2::Create(const char* pFilePath, long face)
344 {
345         if (__isValid)
346         {
347                 return false;
348         }
349
350         int error = FT_Init_FreeType(static_cast<FT_Library*>((void*) &__pFontEngine));
351
352         if (error)
353         {
354                 __CleanUp();
355
356                 return false;
357         }
358
359         error = FT_New_Face(FT_Library(__pFontEngine), pFilePath, face, static_cast<FT_Face*>((void*) &__pFontFace));
360
361         if (error)
362         {
363                 __CleanUp();
364
365                 return false;
366         }
367
368         FT_Face pFace = FT_Face(__pFontFace);
369
370         if ((pFace->charmap == null) && (pFace->num_charmaps > 0))
371         {
372                 FT_Set_Charmap(pFace, pFace->charmaps[0]);
373         }
374
375         __isValid = true;
376
377         return true;
378 }
379
380 bool
381 _FontFt2::CreateStatic(const void* pBuffer, long bufSize, long face)
382 {
383         if (__isValid)
384         {
385                 return false;
386         }
387
388         FT_Face pFace = null;
389
390         int error = FT_Init_FreeType(static_cast<FT_Library*>((void*) &__pFontEngine));
391
392         if (error)
393         {
394                 __CleanUp();
395
396                 return false;
397         }
398
399         __pFontBuffer = const_cast<void*>(pBuffer);
400         __isStaticBuffer = true;
401
402         error = FT_New_Memory_Face(FT_Library(__pFontEngine), (const byte*) __pFontBuffer, bufSize, face, static_cast<FT_Face*>((void*) &__pFontFace));
403
404         if (error)
405         {
406                 __CleanUp();
407
408                 return false;
409         }
410
411         pFace = FT_Face(__pFontFace);
412
413         if ((pFace->charmap == null) && (pFace->num_charmaps > 0))
414         {
415                 FT_Set_Charmap(pFace, pFace->charmaps[0]);
416         }
417
418         __isValid = true;
419         return true;
420 }
421
422 bool
423 _FontFt2::Reload(const void* pBuffer, long bufSize, long face)
424 {
425         if (!__isValid)
426         {
427                 return false;
428         }
429
430         std::unique_ptr<byte[]> pReloadBuffer(new (std::nothrow) byte[bufSize]);
431
432         if (pReloadBuffer == null)
433         {
434                 return false;
435         }
436
437         memcpy(pReloadBuffer.get(), pBuffer, bufSize);
438
439         void* pReloadFace = null;
440
441         int error = FT_New_Memory_Face(FT_Library(__pFontEngine), (const byte*) pReloadBuffer.get(), bufSize, face, static_cast<FT_Face*>((void*) &pReloadFace));
442
443         if (error)
444         {
445                 return false;
446         }
447
448         //clean resource
449         if (__pFontFace)
450         {
451                 FT_Done_Face(FT_Face(__pFontFace));
452                 __pFontFace = null;
453         }
454
455         if (__pFontBuffer && !__isStaticBuffer)
456         {
457                 delete[] static_cast<byte*>(__pFontBuffer);
458         }
459
460         // assign new resource
461         __pFontBuffer = pReloadBuffer.release();
462         __pFontFace = pReloadFace;
463         __isStaticBuffer = false;
464
465         FT_Face pFace = FT_Face(__pFontFace);
466
467         if ((pFace->charmap == null) && (pFace->num_charmaps > 0))
468         {
469                 FT_Set_Charmap(pFace, pFace->charmaps[0]);
470         }
471
472         __isValid = true;
473
474         return true;
475 }
476
477 bool
478 _FontFt2::Reload(const char* filePath, long face)
479 {
480         if (!__isValid)
481         {
482                 return false;
483         }
484
485         void* pReloadFace = null;
486
487         int error = FT_New_Face(FT_Library(__pFontEngine), filePath, face, static_cast<FT_Face*>((void*) &pReloadFace));
488
489         if (error)
490         {
491                 return false;
492         }
493
494         //clean resource
495         if (__pFontFace)
496         {
497                 FT_Done_Face(FT_Face(__pFontFace));
498                 __pFontFace = null;
499         }
500
501         // assign new resource
502         __pFontFace = pReloadFace;
503         __isStaticBuffer = false;
504
505         FT_Face pFace = FT_Face(__pFontFace);
506
507         if ((pFace->charmap == null) && (pFace->num_charmaps > 0))
508         {
509                 FT_Set_Charmap(pFace, pFace->charmaps[0]);
510         }
511
512         __isValid = true;
513
514         return true;
515 }
516
517 void
518 _FontFt2::Destroy(void)
519 {
520         if (!__isValid)
521         {
522                 return;
523         }
524
525         __CleanUp();
526         __isValid = false;
527 }
528
529 bool
530 _FontFt2::FindCache(unsigned long character, int size, int style, Glyph** pOut)
531 {
532         return (__fontCache.get()) ? __fontCache->Find(character, __fontAttrib.size, __fontAttrib.style, pOut) : false;
533 }
534
535 bool
536 _FontFt2::AddCache(unsigned long character, int size, int style, Glyph* pGlyph)
537 {
538         return (__fontCache.get()) ? __fontCache->Add(character, size, style, pGlyph) : false;
539 }
540
541 bool
542 _FontFt2::CleanCache()
543 {
544         return (__fontCache.get()) ? __fontCache->Cleanup() : false;
545 }
546
547 bool
548 _FontFt2::SetAttrib(const Attrib& fontAttrib)
549 {
550         if (!__isValid)
551         {
552                 return false;
553         }
554
555         if (!(fontAttrib.size >= CONVERT_INTEGER_TO_26_6_FIXED_POINT(1)) ||
556                 !(fontAttrib.quality >= 0 && fontAttrib.quality <= 3) ||
557                 !(fontAttrib.xExpansion >= 1) ||
558                 !(CONVERT_26_6_FIXED_POINT_TO_INTEGER(fontAttrib.size) * fontAttrib.xExpansion >= _DEFAULT_RES) ||
559                 !(fontAttrib.boldWeight > 0))
560         {
561                 return false;
562         }
563
564         if (FT_IS_SCALABLE(FT_Face(__pFontFace)) == 0)
565         {
566                 return false;
567         }
568
569         if (FT_Set_Char_Size(FT_Face(__pFontFace), fontAttrib.size * _DEFAULT_RES, fontAttrib.size * _DEFAULT_RES, 1, 1) > 0)
570         {
571                 return false;
572         }
573
574         // set
575         memcpy(&__fontAttrib, &fontAttrib, sizeof(fontAttrib));
576
577         return true;
578 }
579
580 bool
581 _FontFt2::GetAttrib(Attrib& fontAttrib) const
582 {
583         if (!__isValid)
584         {
585                 return false;
586         }
587
588         fontAttrib.angle = __fontAttrib.angle;
589         fontAttrib.quality = __fontAttrib.quality;
590         fontAttrib.size = __fontAttrib.size;
591         fontAttrib.style = __fontAttrib.style;
592         fontAttrib.xExpansion = __fontAttrib.xExpansion;
593         fontAttrib.boldWeight = __fontAttrib.boldWeight;
594
595         return true;
596 }
597
598 bool
599 _FontFt2::GetKerning(unsigned long character1, unsigned long character2, long& xVector, long& yVector) const
600 {
601         if (!__isValid)
602         {
603                 return false;
604         }
605
606         bool isCharacter1InEnglish = false;
607         bool isCharacter2InEnglish = false;
608         FT_Face pFace = null;
609         unsigned long index1 = 0;
610         unsigned long index2 = 0;
611
612         if (character1 >= _INDEX_FIRST && character1 < (_INDEX_FIRST + _INDEX_COUNT))
613         {
614                 isCharacter1InEnglish = true;
615         }
616
617         if (character2 >= _INDEX_FIRST && character2 < (_INDEX_FIRST + _INDEX_COUNT))
618         {
619                 isCharacter2InEnglish = true;
620         }
621
622         if (isCharacter1InEnglish != isCharacter2InEnglish)
623         {
624                 xVector = 0;
625                 yVector = 0;
626                 return true;
627         }
628
629         pFace = FT_Face(__pFontFace);
630         index1 = __GetCharIndex(character1);
631         index2 = __GetCharIndex(character2);
632
633         bool hasKerning = false;
634
635         hasKerning = (FT_HAS_KERNING(pFace) != 0);
636
637         if (hasKerning)
638         {
639                 FT_Vector delta;
640
641                 int isSuccess = FT_Get_Kerning(pFace, index1, index2, ft_kerning_default, &delta);
642
643                 if (isSuccess != 0)  //0 means success.
644                 {
645                         return false;
646                 }
647
648                 const int shiftBit = 6;
649                 xVector = (delta.x >> shiftBit);
650                 yVector = (delta.y >> shiftBit);
651         }
652         else
653         {
654                 xVector = 0;
655                 yVector = 0;
656         }
657
658         return true;
659 }
660
661 bool
662 _FontFt2::LoadGlyph(unsigned long character, Glyph** ppFontGlyphData)
663 {
664         if (!__isValid)
665         {
666                 return false;
667         }
668
669         CHECK_NULL_PARAM(__pFontFace);
670         CHECK_NULL_PARAM(ppFontGlyphData);
671
672         bool rtn = false;
673         rtn = FindCache(character, __fontAttrib.size, __fontAttrib.style, ppFontGlyphData);
674         if (rtn)
675         {
676                 return true;
677         }
678
679         *ppFontGlyphData = null;
680
681         FT_Face pFace = null;
682         FT_UInt ixCurr = character;
683
684         pFace = FT_Face(__pFontFace);
685
686         // is it fixed size?
687         if (!FT_IS_SCALABLE(pFace))
688         {
689                 SysLog(NID_GRP, "[] FT_IS_SCALABLE has been failed");
690         }
691
692         // retrieve glyph index from character code
693         ixCurr = __GetCharIndex(character);
694
695         // set transformation
696         FT_Matrix matrix;
697         FT_Vector pen = {0, 0};
698         __SetTransMatrix(&matrix);
699         FT_Set_Transform(pFace, &matrix, &pen);
700
701         if (__fontAttrib.quality == _IFont::QUALITY_MONO)
702         {
703                 //TODO sunmi557.shin, will not support
704                 FT_Error errCode = 1;
705
706                 errCode = FT_Load_Glyph(pFace, ixCurr, FT_LOAD_RENDER | FT_LOAD_MONOCHROME);
707
708                 if (errCode)
709                 {
710                         SysLogException(NID_GRP, E_SYSTEM, "[E_SYSTEM] FT_Load_Glyph_MONO(errCode = %#x)=", errCode);
711
712                         return false;
713                 }
714         }
715         else if (__fontAttrib.quality == _IFont::QUALITY_LOW ||
716                          __fontAttrib.quality == _IFont::QUALITY_MEDIUM ||
717                          __fontAttrib.quality == _IFont::QUALITY_HIGH)
718         {
719                 FT_Error errCode = 1;
720
721                 bool isSynthetic = (__fontAttrib.style & _IFont::STYLE_BOLD) && !(pFace->style_flags & FT_STYLE_FLAG_BOLD);
722
723                 if (isSynthetic)
724                 {
725                         errCode = FT_Load_Glyph(pFace, ixCurr, FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP);
726                 }
727                 else
728                 {
729                         //errCode = FT_Load_Glyph(pFace, ixCurr, FT_LOAD_RENDER);
730                         errCode = FT_Load_Glyph(pFace, ixCurr, FT_LOAD_DEFAULT);
731                 }
732
733                 if (errCode)  // 0: success
734                 {
735                         SysLogException(NID_GRP, E_SYSTEM, "[E_SYSTEM] FT_Load_Glyph_HighQuality(errCode = %#x)=", errCode);
736
737                         return false;
738                 }
739
740                 if (isSynthetic)
741                 {
742                         FT_Outline_Embolden(&pFace->glyph->outline, __fontAttrib.boldWeight);
743                 }
744
745                 FT_Render_Glyph(pFace->glyph, FT_RENDER_MODE_NORMAL);
746
747         }
748         else
749         {
750                 SysLogException(NID_GRP, E_SYSTEM, "[E_SYSTEM] The quality of the FontFT2 is invalid!");
751
752                 return false;
753         }
754
755         __isLoadGlyph = __ConvertPrivateToImage(pFace->glyph, ppFontGlyphData);
756
757         if (__isLoadGlyph)
758         {
759                 rtn = AddCache(character, __fontAttrib.size, __fontAttrib.style, *ppFontGlyphData);
760         }
761
762         if (*ppFontGlyphData != null)
763         {
764                 (*ppFontGlyphData)->hasOwnerShip = (__isLoadGlyph) ? 1 : 0;
765         }
766
767         return __isLoadGlyph;
768 }
769
770 bool
771 _FontFt2::UnloadGlyph(Glyph** ppFontGlyphData)
772 {
773         if (!__isValid)
774         {
775                 return false;
776         }
777
778         CHECK_NULL_PARAM(ppFontGlyphData);
779
780         if ((*ppFontGlyphData) && ((*ppFontGlyphData)->hasOwnerShip == 0))
781         {
782                 return false;
783         }
784
785         delete[] (char*) (*ppFontGlyphData);
786
787         *ppFontGlyphData = null;
788         __isLoadGlyph = false;
789
790         return false;
791 }
792
793 unsigned long
794 _FontFt2::CheckGlyph(unsigned long character)
795 {
796         return __GetCharIndex(character);
797 }
798
799 bool
800 _FontFt2::GetFontProperty(Property& property) const
801 {
802         if (!__isValid)
803         {
804                 return false;
805         }
806
807         FT_Face face = (FT_Face) __pFontFace;
808
809         if (FT_IS_SCALABLE(face))
810         {
811                 const int shiftBit = 6;
812
813                 // validation check
814                 if (face->size == null)
815                 {
816                         return false;
817                 }
818
819                 // fill out
820                 property.pFamilyName = face->family_name;
821                 property.pStyleName = face->style_name;
822                 property.maxWidth = face->size->metrics.max_advance >> shiftBit;
823                 property.maxHeight = face->size->metrics.height >> shiftBit;
824                 property.baseLine = (face->size->metrics.height + face->size->metrics.descender) >> shiftBit;
825                 property.ascender = face->size->metrics.ascender >> shiftBit;
826                 property.descender = face->size->metrics.descender >> shiftBit; // (-)
827                 property.leading = (face->size->metrics.height - face->size->metrics.ascender + face->size->metrics.descender) >> shiftBit;
828
829                 String familyName = String(property.pFamilyName);
830
831                 if (_CompareFamilyForTitling(familyName))// temp
832                 {
833                         int min = (face->bbox.yMin * face->size->metrics.y_ppem) / face->units_per_EM;
834                         int max = (face->bbox.yMax * face->size->metrics.y_ppem) / face->units_per_EM;
835
836                         if (property.ascender < max)
837                         {
838                                 property.ascender = max;
839                         }
840
841                         if (property.descender > min)
842                         {
843                                 property.descender = min;
844                         }
845
846                         property.maxHeight = property.ascender - property.descender;
847                         property.baseLine = (property.maxHeight + property.descender) >> shiftBit;
848                         property.leading = (property.maxHeight - property.ascender + property.descender) >> shiftBit;
849                 }
850
851                 // shkim, TODO
852                 // engine name and min/max size need to be verified
853                 property.pEngineName = "FreeType2";
854                 property.minSize = 8;
855                 property.maxSize = 540;
856                 property.styleCaps = _IFont::STYLE_ITALIC | _IFont::STYLE_BOLD | _IFont::STYLE_BACKSLANT;
857                 property.fontCaps = _IFont::CAPS_SCALABLE | _IFont::CAPS_ANGLE | _IFont::CAPS_X_EXPANSION | _IFont::CAPS_QUALITY_MONO |
858                                                         _IFont::CAPS_QUALITY_LOW | _IFont::CAPS_QUALITY_MEDIUM | _IFont::CAPS_QUALITY_HIGH;
859         }
860         else
861         {
862                 return false;
863         }
864
865         return true;
866 }
867
868 Tizen::Base::Collection::HashMapT<Tizen::Base::String, _IFont::SharedFontResource>*
869 _FontFt2::GetFallbackMap()
870 {
871         return &__fallbackFontMap;
872 }
873
874 bool
875 _FontFt2::GetGlyphList(const _Util::String& text, Tizen::Base::Collection::IListT<_IFont::Glyph *>& out, bool isRtl, int script) const
876 {
877         //hb_font_funcs_t *ffuncs;
878         FT_Face face = null;
879         hb_buffer_t *hBuffer = null;
880         hb_glyph_position_t *positions = null;
881         hb_glyph_info_t *infos = null;
882         unsigned int slen;
883
884         /*FriBidiChar *friText = new (std::nothrow) FriBidiChar[length];
885         FriBidiCharType *ctypes = new (std::nothrow) FriBidiCharType[length];
886         FriBidiLevel *emblevels = new (std::nothrow) FriBidiLevel[length];
887         FriBidiJoiningType *join_types = new (std::nothrow) FriBidiJoiningType[length];
888         FriBidiParType base_direction = FRIBIDI_PAR_ON;
889         FriBidiCharType type;
890         char *ouputChar = new (std::nothrow) char[length];*/
891
892         //int last_break = 0;
893         //bool bRTL = true;
894
895 /*
896           ffuncs = hb_font_funcs_create ();
897           hb_font_funcs_set_glyph_h_advance_func (ffuncs, glyph_h_advance_func, NULL, NULL);
898           hb_font_funcs_set_glyph_func (ffuncs, glyph_func, NULL, NULL);
899           hb_font_funcs_set_glyph_h_kerning_func (ffuncs, glyph_h_kerning_func, NULL, NULL);
900           hb_font_set_funcs (hFont, ffuncs, NULL, NULL);*/
901
902         // if(hb_version_check(0, 9, 0))//0.9.0
903          // {
904          //      hBuffer = hb_buffer_create();
905                 // hb_buffer_set_unicode_funcs(hBuffer, hb_unicode_funcs_get_default());
906                 // hb_buffer_set_language(hBuffer, hb_language_from_string("th", -1));
907          // }
908          //else// 0.7.0
909          // {
910         face = FT_Face(__pFontFace);
911
912         hb_font_t *hFont = hb_ft_font_create (face, NULL);
913         hb_font_t *hSubFont = hb_font_create_sub_font(hFont);
914         hb_font_destroy (hFont);
915
916         hBuffer = hb_buffer_create();
917         hb_buffer_set_unicode_funcs(hBuffer, hb_unicode_funcs_get_default());
918         //hb_buffer_set_language(hBuffer, hb_language_from_string("th"));
919
920         if (isRtl)
921         {
922                 //hb_buffer_set_language(hBuffer, hb_language_from_string("ar", -1));
923                 hb_buffer_set_script(hBuffer, _HarfbuzzScript[script]);
924                 hb_buffer_set_direction(hBuffer, HB_DIRECTION_RTL);
925         }
926         else
927         {
928                 //hb_buffer_set_language(hBuffer, hb_language_from_string("en", -1));
929                 //hb_buffer_set_script(hBuffer, HB_SCRIPT_THAI);
930                 //hb_buffer_set_direction(hBuffer, HB_DIRECTION_LTR);
931                 hb_buffer_set_script(hBuffer, _HarfbuzzScript[script]);
932                 hb_buffer_set_direction(hBuffer, HB_DIRECTION_LTR);
933         }
934
935         if (sizeof(wchar_t) == sizeof(uint32_t))
936         {
937                 hb_buffer_add_utf32(hBuffer, (const uint32_t*)text.pStart, text.length, 0, text.length);
938         }
939         else
940         {
941                 uint32_t* pDst = new (std::nothrow) uint32_t[text.length + 1];
942
943                 if (pDst)
944                 {
945                         {
946                                 const wchar_t* pSrc = text.pStart;
947
948                                 uint32_t* pDstBegin = pDst;
949                                 uint32_t* pDstEnd = pDstBegin + text.length;
950
951                                 while (pDstBegin < pDstEnd)
952                                 {
953                                         *pDstBegin++ = *pSrc++;
954                                 }
955
956                                 *pDstBegin = 0;
957                         }
958
959                         hb_buffer_add_utf32(hBuffer, pDst, text.length, 0, text.length);
960
961                         delete[] pDst;
962                 }
963         }
964
965          /*{
966                  hb_font_funcs_t *font_funcs = hb_font_funcs_create();
967
968            hb_font_funcs_set_glyph_h_advance_func(font_funcs, _evas_common_font_ot_hb_get_glyph_advance, NULL, NULL);
969            hb_font_funcs_set_glyph_h_kerning_func(font_funcs, _evas_common_font_ot_hb_get_kerning, NULL, NULL);
970
971                  hb_font_set_funcs(hSubFont, font_funcs, fi, NULL);
972          }*/
973
974         hb_shape (hSubFont, hBuffer, NULL, 0);
975
976         slen = hb_buffer_get_length (hBuffer);
977         positions = hb_buffer_get_glyph_positions (hBuffer, NULL);
978         infos = hb_buffer_get_glyph_infos (hBuffer, NULL);
979
980          //_IFont::Glyph *pFontGlyphData = (_IFont::Glyph*) new (std::nothrow) char[sizeof(_IFont::Glyph) + (image.bytesPerLine * image.height)];
981
982         out.RemoveAll();
983
984         for(unsigned int i = 0; i < slen; i++)
985         {
986                 FT_UInt glyph_index = infos->codepoint;
987
988                 _IFont::GlyphBitmap image;
989
990                 FT_Error error = FT_Load_Glyph(face, glyph_index, /*FT_LOAD_RENDER*/FT_LOAD_DEFAULT/* | FT_LOAD_NO_BITMAP*/);
991                 if(error)
992                 {
993                         continue;
994                 }
995
996                 error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
997                 if(error)
998                 {
999                         continue;
1000                 }
1001
1002                 FT_GlyphSlot pSlot = FT_GlyphSlot(face->glyph);
1003
1004                 switch (pSlot->bitmap.pixel_mode)
1005                 {
1006                         case ft_pixel_mode_mono:
1007                                 image.depth = 1;
1008                                 break;
1009
1010                         case ft_pixel_mode_grays:
1011                                 image.depth = 8;
1012                                 break;
1013
1014                         default:
1015                                 continue;
1016                 }
1017
1018                 image.width = pSlot->bitmap.width;
1019                 image.height = pSlot->bitmap.rows;
1020                 image.bytesPerLine = pSlot->bitmap.pitch;
1021                 image.pBitmap = pSlot->bitmap.buffer;
1022
1023                 _IFont::Glyph *pFontGlyphData = (_IFont::Glyph*) new (std::nothrow) char[sizeof(_IFont::Glyph) + (image.bytesPerLine * image.height)];
1024
1025                 if (pFontGlyphData == null)
1026                         continue;
1027
1028                 pFontGlyphData->id = 0;
1029                 pFontGlyphData->xOffset = (positions->x_offset >> 6) + pSlot->bitmap_left;
1030                 pFontGlyphData->yOffset = (positions->y_offset >> 6) + pSlot->bitmap_top;
1031                 pFontGlyphData->xAdvance = pSlot->advance.x << (_FIXED_SHIFT - 6);
1032                 pFontGlyphData->yAdvance = -(pSlot->advance.y << (_FIXED_SHIFT - 6));
1033                 //pFontGlyphData->xOffset = positions->x_offset;
1034                 //pFontGlyphData->yOffset = positions->y_offset;
1035                 //pFontGlyphData->xAdvance = positions->x_advance;
1036                 //pFontGlyphData->yAdvance = positions->y_advance;
1037                 pFontGlyphData->image = image;
1038
1039                 pFontGlyphData->image.pBitmap = (unsigned char*)(pFontGlyphData + 1);
1040                 memcpy(pFontGlyphData->image.pBitmap, image.pBitmap, image.bytesPerLine * image.height);
1041
1042                 out.Add(pFontGlyphData);
1043
1044                 infos++;
1045                 positions++;
1046         }
1047
1048         hb_font_destroy (hSubFont);
1049         hb_buffer_destroy(hBuffer);
1050
1051         return true;
1052 }
1053
1054 void
1055 _FontFt2::__CleanUp()
1056 {
1057         if (__pFontFace)
1058         {
1059                 FT_Done_Face(FT_Face(__pFontFace));
1060                 __pFontFace = null;
1061         }
1062
1063         if (__pFontEngine)
1064         {
1065                 FT_Done_FreeType(FT_Library(__pFontEngine));
1066                 __pFontEngine = null;
1067         }
1068
1069         if (__pFontBuffer && !__isStaticBuffer)
1070         {
1071                 delete[] static_cast<byte*>(__pFontBuffer);
1072         }
1073
1074         __pFontBuffer = null;
1075         __isStaticBuffer = false;
1076 }
1077
1078 unsigned long
1079 _FontFt2::__GetCharIndex(unsigned long character) const
1080 {
1081         if (!__isValid)
1082         {
1083                 return 0;
1084         }
1085
1086         FT_Face pFace = FT_Face(__pFontFace);
1087         if (pFace == null)
1088         {
1089                 return false;
1090         }
1091
1092         if (pFace->charmap)
1093         {
1094                 unsigned long ixCurr = FT_Get_Char_Index(pFace, character);
1095
1096                 return ixCurr;
1097         }
1098
1099         return character;
1100 }
1101
1102 bool
1103 _FontFt2::__ConvertPrivateToImage(void* pData1, _IFont::Glyph** ppFontGlyphData)
1104 {
1105         if (!__isValid)
1106         {
1107                 return false;
1108         }
1109
1110         FT_GlyphSlot pSlot = FT_GlyphSlot(pData1);
1111
1112         _IFont::GlyphBitmap image;
1113
1114         switch (pSlot->bitmap.pixel_mode)
1115         {
1116         case ft_pixel_mode_mono:
1117                 image.depth = 1;
1118                 break;
1119         case ft_pixel_mode_grays:
1120                 image.depth = 8;
1121                 break;
1122         default:
1123                 return false;
1124         }
1125
1126         image.width = pSlot->bitmap.width;
1127         image.height = pSlot->bitmap.rows;
1128         image.bytesPerLine = pSlot->bitmap.pitch;
1129         image.pBitmap = pSlot->bitmap.buffer;
1130
1131         *ppFontGlyphData = (_IFont::Glyph*) new (std::nothrow) char[sizeof(_IFont::Glyph) + (image.bytesPerLine * image.height)];
1132
1133         if (*ppFontGlyphData == null)
1134         {
1135                 return false;
1136         }
1137
1138         (*ppFontGlyphData)->id = 0;
1139         (*ppFontGlyphData)->xOffset = pSlot->bitmap_left << _FIXED_SHIFT;
1140         (*ppFontGlyphData)->yOffset = pSlot->bitmap_top << _FIXED_SHIFT;
1141         (*ppFontGlyphData)->xAdvance = pSlot->advance.x << (_FIXED_SHIFT - 6);
1142         (*ppFontGlyphData)->yAdvance = -(pSlot->advance.y << (_FIXED_SHIFT - 6));
1143         (*ppFontGlyphData)->hasOwnerShip = 0;
1144         (*ppFontGlyphData)->image = image;
1145
1146         // shkim, set the memory address of bitmap to the allocated by ourself above
1147         //(*pFontGlyphData)->image.bitmap = (unsigned char*)((*pFontGlyphData) + 1);
1148
1149         if (image.width == 0 || image.height == 0)
1150         {
1151                 return true;
1152         }
1153
1154         //memcpy((*ppFontGlyphData)->image.bitmap, image.bitmap, image.bytesPerLine * image.height);
1155
1156         return true;
1157 }
1158
1159 bool
1160 _FontFt2::__SetTransMatrix(void* pMatrix)
1161 {
1162         if (!__isValid)
1163         {
1164                 return false;
1165         }
1166
1167         if (pMatrix == null)
1168         {
1169                 return true;
1170         }
1171
1172         FT_Matrix* pTrans = (FT_Matrix*) pMatrix;
1173
1174         double radian = _M_PI / 180.0;
1175
1176         if (_IsEqual(0.0f, __fontAttrib.angle))
1177         {
1178                 // apply font size
1179                 pTrans->xx = (FT_Fixed) (0x10000 * (__fontAttrib.xExpansion)) / 100;
1180                 pTrans->xy = (FT_Fixed) 0;
1181                 pTrans->yx = (FT_Fixed) 0;
1182                 pTrans->yy = (FT_Fixed) 0x10000;
1183
1184                 // apply italic style
1185                 if (__fontAttrib.style & _IFont::STYLE_ITALIC)
1186                 {
1187                         pTrans->xy = (FT_Fixed) (sin(_ITALIC_ANGLE * radian) * 0x10000);
1188                 }
1189                 else if (__fontAttrib.style & _IFont::STYLE_BACKSLANT)
1190                 {
1191                         pTrans->xy = (FT_Fixed) (sin(-_ITALIC_ANGLE * radian) * 0x10000);
1192                 }
1193         }
1194         else
1195         {
1196                 double radAngle = __fontAttrib.angle * radian;
1197
1198                 pTrans->xx = (FT_Fixed) (cos(radAngle) * (__fontAttrib.xExpansion) * 0x10000) / 100;
1199                 pTrans->xy = (FT_Fixed) (-sin(radAngle) * 0x10000);
1200                 pTrans->yx = (FT_Fixed) (sin(radAngle) * (__fontAttrib.xExpansion) * 0x10000) / 100;
1201                 pTrans->yy = (FT_Fixed) (cos(radAngle) * 0x10000);
1202
1203                 // apply italic style
1204                 if (__fontAttrib.style & _IFont::STYLE_ITALIC)
1205                 {
1206                         pTrans->xy = (FT_Fixed) ((cos(radAngle) * tan(_ITALIC_ANGLE * radian) - sin(radAngle)) * 0x10000);
1207                         pTrans->yy = (FT_Fixed) ((sin(radAngle) * tan(_ITALIC_ANGLE * radian) + cos(radAngle)) * 0x10000);
1208                 }
1209                 else if (__fontAttrib.style & _IFont::STYLE_BACKSLANT)
1210                 {
1211                         pTrans->xy = (FT_Fixed) ((cos(radAngle) * tan(-_ITALIC_ANGLE * radian) - sin(radAngle)) * 0x10000);
1212                         pTrans->yy = (FT_Fixed) ((sin(radAngle) * tan(-_ITALIC_ANGLE * radian) + cos(radAngle)) * 0x10000);
1213                 }
1214         }
1215
1216         return true;
1217 }
1218
1219 }} // Tizen::Graphics