faa0849b6a20e62e447a9633ffb2e209dce2b00a
[framework/osp/uifw.git] / src / graphics / FGrp_FontRsrcManager.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_FontRsrcManager.cpp
20  * @brief       This is the cpp file for _FontRsrcManager class.
21  *
22  */
23
24 #include <new>
25 #include <memory>
26
27 #include <unique_ptr.h>
28 #include <pthread.h>
29
30 #include <fontconfig/fontconfig.h>
31
32 #include <FAppApp.h>
33 #include <FBaseColIHashCodeProviderT.h>
34 #include <FBaseUtilStringUtil.h>
35 #include <FIoFile.h>
36 #include <FGrpFontCommon.h>
37 #include <FIoDirectory.h>
38 #include <FBaseUtilStringTokenizer.h>
39
40 #include <FBaseSysLog.h>
41
42 #include "FGrp_Font.h"
43 #include "FGrp_FontRsrcManager.h"
44 #include "FGrp_FontMemoryManager.h"
45 #include "FGrp_FontFt2.h"
46
47 #define USE_REMOVE_ALL_CACHE
48 #define USE_MMAP
49
50 #include "util/FGrp_UtilTemplate.h"
51
52
53 #define IF_NOT_INITIALIZED(code) if (_pImpl == null) \
54         { \
55                 code; \
56         }
57
58 using namespace Tizen::App;
59 using namespace Tizen::Io;
60 using namespace Tizen::Base;
61 using namespace Tizen::Base::Collection;
62 using namespace Tizen::Base::Utility;
63 using namespace Tizen::Graphics;
64 using namespace Tizen::System;
65
66
67 namespace // unnamed
68 {
69
70 const int _DEFAULT_FONT_ENGINE = 0;
71 const int _DEFAULT_FONT_FACE = 0;
72 const char* _DEFAULT_SYSTEM_FONT = "DefaultSystemFont";
73 const char* _DEFAULT_SYSTEM_BOLD_FONT = "DefaultSystemBoldFont";
74 const _Util::FixedPoint26_6 _SYSTEM_DEFAULT_FONT_SIZE(16);
75
76 class _FontNull
77         : public Tizen::Graphics::_IFont
78 {
79 public:
80         virtual bool SetAttrib(const Attrib& fontAttrib)
81         {
82                 return false;
83         }
84
85         virtual bool GetAttrib(Attrib& fontAttrib) const
86         {
87                 return false;
88         }
89
90         virtual bool GetKerning(unsigned long character1, unsigned long character2, long& xVector, long& yVector) const
91         {
92                 return false;
93         }
94
95         virtual bool LoadGlyph(unsigned long character, Glyph** pFontGlyphData)
96         {
97                 return false;
98         }
99
100         virtual bool UnloadGlyph(Glyph** pFontGlyphData)
101         {
102                 return false;
103         }
104
105         virtual unsigned long CheckGlyph(unsigned long character)
106         {
107                 return 0;
108         }
109
110         virtual bool GetGlyphList(const _Util::String& text, Tizen::Base::Collection::IListT<_IFont::Glyph *>& out, int script)
111         {
112                 return false;
113         }
114
115         virtual bool GetFontSizeProperty(SizeProperty& sizeProperty) const
116         {
117                 return false;
118         }
119
120         virtual bool GetFontProperty(Property& property) const
121         {
122                 return false;
123         }
124
125         virtual FontMapT* GetFallbackMap(void)
126         {
127                 return null;
128         }
129
130         virtual bool IsEmoji(void) const
131         {
132                 return false;
133         }
134
135 protected:
136         virtual bool Create(const void* pBuffer, long bufSize, long face = 0)
137         {
138                 return false;
139         }
140
141         virtual bool Create(const char* pFilePath, long face = 0)
142         {
143                 return false;
144         }
145
146         virtual bool CreateStatic(const void* pBuffer, long bufSize, long face = 0)
147         {
148                 return false;
149         }
150
151         virtual bool Reload(const void* pBuffer, long bufSize, long face = 0)
152         {
153                 return false;
154         }
155
156         virtual bool Reload(const char* filePath, long face = 0)
157         {
158                 return false;
159         }
160
161         virtual void Destroy(void) {}
162
163         virtual bool FindCache(unsigned long character, _Util::FixedPoint26_6 size, int style, Glyph** pOut)
164         {
165                 return false;
166         }
167
168         virtual bool AddCache(unsigned long character, _Util::FixedPoint26_6 size, int style, Glyph* pGlyph)
169         {
170                 return false;
171         }
172
173         virtual bool CleanCache(void)
174         {
175                 return false;
176         }
177 }; // _FontNull
178
179 template<class T>
180 class _FontHashCodeProvider
181         : public IHashCodeProviderT <T>
182 {
183 public:
184         virtual int GetHashCode(const T& obj) const
185         {
186                 return obj.GetHashCode();
187         }
188 }; // _FontHashCodeProvider
189
190 template<class T>
191 class _FontComparer
192         : public IComparerT <T>
193 {
194 public:
195         virtual result Compare(const T& obj1, const T& obj2, int& cmp) const
196         {
197                 String& objString1 = static_cast <String&>(const_cast <T&>(obj1));
198                 String& objString2 = static_cast <String&>(const_cast <T&>(obj2));
199
200                 cmp = objString1.CompareTo(objString2);
201
202                 return E_SUCCESS;
203         }
204 }; // _FontComparer
205
206 #ifdef USE_HASHMAP_FOR_FONT
207 template<class T>
208 class _FontHashCodeProviderEx
209         : public IHashCodeProviderT <T>
210 {
211 public:
212         virtual int GetHashCode(const T& obj) const
213         {
214                 return reinterpret_cast<int>(obj.c_str());
215         }
216 }; // _FontHashCodeProviderEx
217
218 template<class T>
219 class _FontComparerEx
220         : public IComparerT <T>
221 {
222 public:
223         virtual result Compare(const T& obj1, const T& obj2, int& cmp) const
224         {
225                 cmp = wcscmp((wchar_t*)obj1.c_str(), (wchar_t*)obj1.c_str());
226
227                 return E_SUCCESS;
228         }
229 }; // _FontComparerEx
230 #endif
231 }
232
233 namespace Tizen { namespace Graphics
234 {
235
236 _FontRsrcManager* _FontRsrcManager::__pTheInstance = null;
237
238 _FontRsrcManager::_FontRsrcManager()
239         : __isAppFontListInitialized(false)
240 {
241         static _FontHashCodeProvider<String> fontHashCodeProvider;
242         static _FontComparer<String> fontComparer;
243
244         // are you worry about failing to construct?
245         // but, HashMapT only can give E_SUCCESS/E_INVALID_ARG/E_OUT_OF_MEMORY.
246         // it means, if you ha2ve already verified input param, don't need to concern yourself.
247         // even though you have E_OUT_OF_MEMORY, it's already out of our control,
248         // and surely the other member function can give a error message.
249 #ifdef USE_HASHMAP_FOR_FONT
250         static _FontHashCodeProviderEx<_Util::WString> fontHashCodeProviderEx;
251         static _FontComparerEx<_Util::WString> fontComparerEx;
252         __fontRsrcMap.Construct(0, 0, fontHashCodeProviderEx, fontComparerEx);
253 #endif
254         __appFontMap.Construct(0, 0, fontHashCodeProvider, fontComparer);
255
256         __defaultSystemFontPath.Clear();
257         __defaultSystemBoldFontPath.Clear();
258         __pDefaultSystemFont = null;
259
260         FcInit();
261
262         const unsigned long cacheMemorySize = 1 * 1024 * 1024;
263         std::unique_ptr<_FontMemoryManager> pMemoryMgr(new (std::nothrow) _FontMemoryManager(_FontMemoryManager::TYPE_SIZE, cacheMemorySize));
264
265         if (pMemoryMgr != null && pMemoryMgr->IsValid())
266         {
267                 __pFontMemoryManager = pMemoryMgr.release();
268         }
269
270         SysAssert(__pFontMemoryManager != null);
271 }
272
273 _FontRsrcManager::~_FontRsrcManager()
274 {
275 #ifdef USE_HASHMAP_FOR_FONT
276         __fontRsrcMap.RemoveAll();
277 #else
278         __fontRsrcMap.clear();
279 #endif
280
281         __appFontMap.RemoveAll();
282
283         delete __pDefaultSystemFont;
284         delete __pFontMemoryManager;
285
286         FcFini();
287 }
288
289 result
290 _FontRsrcManager::GetFont(const Tizen::Base::String& fontPath, int style, _Util::FixedPoint26_6 size, SharedFontResource& out)
291 {
292         _Util::WString fontPathTemp(fontPath.GetPointer());
293
294         SharedFontResource sharedFont;
295         _IFont* pFont = null;
296
297         bool rtn = false;
298
299         //--------------------------------------------------------------------------
300         // validation check of input param
301         //
302         // in case input fontPath is indicating folder,
303         // we should return 'E_UNSUPPORTED_FORMAT' as bads 2.0 did.
304         //--------------------------------------------------------------------------
305         {
306                 FileAttributes attr;
307                 result r = File::GetAttributes(fontPath, attr);
308                 if (IsFailed(r))
309                 {
310                         return E_FILE_NOT_FOUND;
311                 }
312                 else if (attr.IsDirectory())
313                 {
314                         return E_UNSUPPORTED_FORMAT;
315                 }
316         }
317
318         //--------------------------------------------------------------------------
319         // step 1
320         //
321         // if we already have specified resoruce,
322         // return it with increasing reference count
323         //--------------------------------------------------------------------------
324         rtn = __SearchFont(fontPathTemp, sharedFont);
325
326         if (rtn)
327         {
328                 out = sharedFont;
329
330                 return E_SUCCESS;
331         }
332
333         //--------------------------------------------------------------------------
334         // step 2
335         //
336         // create new font
337         //--------------------------------------------------------------------------
338         {
339 #ifdef USE_MMAP
340                 ByteBuffer* pBuffer = StringUtil::StringToUtf8N(fontPath);
341                 if (pBuffer == null)
342                 {
343                         return false;
344                 }
345                 std::auto_ptr<ByteBuffer> pathString(pBuffer);
346
347                 rtn = __CreateFont(_DEFAULT_FONT_ENGINE, (char*)pathString->GetPointer(), _DEFAULT_FONT_FACE, &pFont);
348 #else
349                 int fileLength = 0;
350                 int readLength = 0;
351                 File file;
352
353                 result r = file.Construct(fontPath, L"rb");
354                 SysTryReturnResult(NID_GRP, r == E_SUCCESS, E_SYSTEM, "Failed to open file");
355
356                 r = file.Seek(FILESEEKPOSITION_END, 0);
357                 SysTryReturnResult(NID_GRP, r == E_SUCCESS, E_SYSTEM, "Failed to seek file");
358
359                 fileLength = file.Tell();
360                 SysTryReturnResult(NID_GRP, fileLength > 0, E_SYSTEM, "The length of the file is not positive");
361
362                 r = file.Seek(FILESEEKPOSITION_BEGIN, 0);
363                 SysTryReturnResult(NID_GRP, r == E_SUCCESS, E_SYSTEM, "Failed to seek file");
364
365                 std::unique_ptr<unsigned char[]> buffer(new (std::nothrow) unsigned char[fileLength]);
366                 SysTryReturnResult(NID_GRP, buffer, E_OUT_OF_MEMORY, "Failed to create font instance");
367
368                 readLength = file.Read(buffer.get(), fileLength);
369                 SysTryReturnResult(NID_GRP, readLength == fileLength, E_SYSTEM, "Failed to read file");
370
371                 // create font
372                 rtn = __CreateFont(_DEFAULT_FONT_ENGINE, buffer.get(), fileLength, _DEFAULT_FONT_FACE, &pFont);
373 #endif
374                 std::auto_ptr<_IFont> autoPtrFont(pFont);
375                 SysTryReturnResult(NID_GRP, rtn && autoPtrFont.get() != null, E_UNSUPPORTED_FORMAT, "Failed to create _IFont instance");
376
377                 // make shared resource
378                 sharedFont.reset(autoPtrFont.release());
379
380                 _IFont::Attrib fontAttrib;
381                 rtn = pFont->GetAttrib(fontAttrib);
382                 SysTryReturnResult(NID_GRP, rtn, E_SYSTEM, "Failed to get font attribute");
383
384                 fontAttrib.size = size;
385                 fontAttrib.style = 0;
386                 fontAttrib.style |= (style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
387                 fontAttrib.style |= (style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
388
389                 rtn = pFont->SetAttrib(fontAttrib);
390                 SysTryReturnResult(NID_GRP, rtn, E_SYSTEM, "Failed to set font attribute");
391         }
392
393         //--------------------------------------------------------------------------
394         // step 3
395         //
396         // add newly created font resource to rsrc manager
397         //--------------------------------------------------------------------------
398         rtn = __AddFont(fontPathTemp, sharedFont);
399         SysTryReturnResult(NID_GRP, rtn, E_SYSTEM, "Failed to add font resource into the shared container.");
400
401         // set
402         out = sharedFont;
403
404         //--------------------------------------------------------------------------
405         // step 4
406         //
407         // remove unused font
408         //--------------------------------------------------------------------------
409         __RemoveUnusedFont();
410
411         return E_SUCCESS;
412 }
413
414 result
415 _FontRsrcManager::GetTempFont(const Tizen::Base::String& fontPath, int style, _Util::FixedPoint26_6 size, SharedFontResource& out)
416 {
417         _Util::WString fontPathTemp(fontPath.GetPointer());
418
419         SharedFontResource sharedFont;
420         _IFont* pFont = null;
421         //_FontCache* pFontCache = null;
422         bool rtn = false;
423         //unsigned char* pBuffer = null;
424
425         //--------------------------------------------------------------------------
426         // validation check of input param
427         //
428         // in case input fontPath is indicating folder,
429         // we should return 'E_UNSUPPORTED_FORMAT' as bads 2.0 did.
430         //--------------------------------------------------------------------------
431         {
432                 FileAttributes attr;
433                 result r = File::GetAttributes(fontPath, attr);
434                 if (IsFailed(r))
435                 {
436                         return E_FILE_NOT_FOUND;
437                 }
438                 else if (attr.IsDirectory())
439                 {
440                         return E_UNSUPPORTED_FORMAT;
441                 }
442         }
443
444         //--------------------------------------------------------------------------
445         // step 1
446         //
447         // if we already have specified resoruce,
448         // return it with increasing reference count
449         //--------------------------------------------------------------------------
450         rtn = __SearchFont(fontPathTemp, sharedFont);
451
452         if (rtn)
453         {
454                 out = sharedFont;
455
456                 return E_SUCCESS;
457         }
458
459         //--------------------------------------------------------------------------
460         // step 2
461         //
462         // create new font
463         //--------------------------------------------------------------------------
464         {
465                 ByteBuffer* pBuffer = StringUtil::StringToUtf8N(fontPath);
466                 if (pBuffer == null)
467                 {
468                         return false;
469                 }
470                 std::auto_ptr<ByteBuffer> pathString(pBuffer);
471
472                 rtn = __CreateFont(_DEFAULT_FONT_ENGINE, (char*)pathString->GetPointer(), _DEFAULT_FONT_FACE, &pFont);
473
474                 std::auto_ptr<_IFont> autoPtrFont(pFont);
475                 SysTryReturnResult(NID_GRP, rtn && autoPtrFont.get() != null, E_UNSUPPORTED_FORMAT, "Failed to create _IFont instance");
476
477                 // make shared resource
478                 sharedFont.reset(autoPtrFont.release());
479
480                 _IFont::Attrib fontAttrib;
481                 rtn = pFont->GetAttrib(fontAttrib);
482                 SysTryReturnResult(NID_GRP, rtn, E_SYSTEM, "Failed to get font attribute");
483
484                 fontAttrib.size = size;
485                 fontAttrib.style = 0;
486                 fontAttrib.style |= (style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
487                 fontAttrib.style |= (style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
488
489                 rtn = pFont->SetAttrib(fontAttrib);
490                 SysTryReturnResult(NID_GRP, rtn, E_SYSTEM, "Failed to set font attribute");
491         }
492
493         // set
494         out = sharedFont;
495
496         return E_SUCCESS;
497 }
498
499 result
500 _FontRsrcManager::AddFont(const _Util::WString& fontPath, SharedFontResource& out)
501 {
502         bool rtn = false;
503
504         rtn = __AddFont(fontPath, out);
505         SysTryReturnResult(NID_GRP, rtn, E_SYSTEM, "Failed to add font resource into the shared container.");
506
507         return E_SUCCESS;
508 }
509
510
511 bool
512 _FontRsrcManager::SearchFont(const _Util::WString& fontName)
513 {
514         SharedFontResource sharedFont;
515
516         return (__SearchFont(fontName, sharedFont) == true);
517 }
518
519 result
520 _FontRsrcManager::GetFont(const byte* pFontData, int fontDataSize, int style, _Util::FixedPoint26_6 size, SharedFontResource& out)
521 {
522         SharedFontResource sharedFont;
523         _IFont* pFont = null;
524
525         //--------------------------------------------------------------------------
526         // step 1
527         //
528         // create new font with user resource.
529         //--------------------------------------------------------------------------
530         bool rtn = __CreateFont(_DEFAULT_FONT_ENGINE, pFontData, fontDataSize, _DEFAULT_FONT_FACE, &pFont);
531         std::auto_ptr<_IFont> autoPtrFont(pFont);
532         SysTryReturnResult(NID_GRP, rtn && autoPtrFont.get() != null, E_UNSUPPORTED_FORMAT, "Failed to create _IFont");
533
534         // make shared resource
535         sharedFont.reset(autoPtrFont.release());
536
537         _IFont::Attrib fontAttrib;
538         rtn = pFont->GetAttrib(fontAttrib);
539         SysTryReturnResult(NID_GRP, rtn, E_SYSTEM, "Failed to get font attribute");
540
541         fontAttrib.size = size;
542         fontAttrib.style = 0;
543         fontAttrib.style |= (style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
544         fontAttrib.style |= (style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
545
546         rtn = pFont->SetAttrib(fontAttrib);
547         SysTryReturnResult(NID_GRP, rtn, E_SYSTEM, "Failed to set font attribute");
548
549         //--------------------------------------------------------------------------
550         // step 2
551         //
552         // add newly created font resource to rsrc manager
553         //--------------------------------------------------------------------------
554         static long long idx = 0;
555
556         String fontName(L"UserMemoryFont");
557         fontName.Append(idx++);
558
559         _Util::WString fontNameTemp(fontName.GetPointer());
560
561         rtn = __AddFont(fontNameTemp, sharedFont);
562         SysTryReturnResult(NID_GRP, rtn, E_SYSTEM, "Failed to add font resrouce into the shared container.");
563
564         // set
565         out = sharedFont;
566
567         //--------------------------------------------------------------------------
568         // step 3
569         //
570         // remove unused font
571         //--------------------------------------------------------------------------
572         __RemoveUnusedFont();
573
574         return E_SUCCESS;
575 }
576
577 result
578 _FontRsrcManager::GetFont(int style, _Util::FixedPoint26_6 size, SharedFontResource& out)
579 {
580         SharedFontResource sharedFont;
581         bool isBold = (style & FONT_STYLE_BOLD) ? true : false;
582
583         String systemFontName = isBold ? _DEFAULT_SYSTEM_BOLD_FONT : _DEFAULT_SYSTEM_FONT;
584
585         _Util::WString systemFontNameTemp(systemFontName.GetPointer());
586
587         _IFont* pFont = null;
588         bool rtn = false;
589
590         //--------------------------------------------------------------------------
591         // step 1
592         //
593         // if we already have specified resoruce,
594         // return it with increasing reference count
595         //--------------------------------------------------------------------------
596         rtn = __SearchFont(systemFontNameTemp, sharedFont);
597
598         if (rtn)
599         {
600                 out = sharedFont;
601
602                 return E_SUCCESS;
603         }
604
605         //--------------------------------------------------------------------------
606         // step 2
607         //
608         // create new font with default font resource.
609         //--------------------------------------------------------------------------
610
611         isBold ? __defaultSystemBoldFontPath.Clear() : __defaultSystemFontPath.Clear();
612
613         const String& defaultSystemFontPath = __GetDefaultSystemFontPath(isBold);
614         SysTryReturnResult(NID_GRP, defaultSystemFontPath.IsEmpty() == false, E_SYSTEM, "Failed to get default system font path");
615
616         {
617 #ifdef USE_MMAP
618                 ByteBuffer* pBuffer = StringUtil::StringToUtf8N(defaultSystemFontPath);
619                 if (pBuffer == null)
620                 {
621                         return false;
622                 }
623                 std::auto_ptr<ByteBuffer> pathString(pBuffer);
624
625                 rtn = __CreateFont(_DEFAULT_FONT_ENGINE, (char*)pathString->GetPointer(), _DEFAULT_FONT_FACE, &pFont);
626 #else
627                 int fileLength = 0;
628                 File file;
629
630                 result r = file.Construct(defaultSystemFontPath, L"rb");
631                 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to open file", GetErrorMessage(r));
632
633                 r = file.Seek(FILESEEKPOSITION_END, 0);
634                 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to seek file", GetErrorMessage(r));
635
636                 fileLength = file.Tell();
637                 SysTryReturn(NID_GRP, fileLength > 0, r, r, "[%s] The length of the file is not positive", GetErrorMessage(r));
638
639                 r = file.Seek(FILESEEKPOSITION_BEGIN, 0);
640                 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to seek file", GetErrorMessage(r));
641
642                 std::unique_ptr<unsigned char[]> autoPtrBuffer(new (std::nothrow) unsigned char[fileLength]);
643                 SysTryReturn(NID_GRP, autoPtrBuffer, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to create buffer of the file length");
644
645                 file.Read(autoPtrBuffer.get(), fileLength);
646
647                 rtn = __CreateFont(_DEFAULT_FONT_ENGINE, autoPtrBuffer.get(), fileLength, _DEFAULT_FONT_FACE, &pFont);
648 #endif
649                 std::auto_ptr<_IFont> autoPtrFont(pFont);
650                 SysTryReturnResult(NID_GRP, rtn && autoPtrFont.get() != null, E_UNSUPPORTED_FORMAT, "Failed to create _IFont instance");
651
652                 // make shared resource
653                 sharedFont.reset(autoPtrFont.release());
654
655                 _IFont::Attrib fontAttrib;
656                 rtn = pFont->GetAttrib(fontAttrib);
657                 SysTryReturnResult(NID_GRP, rtn, E_SYSTEM, "Failed to get font attribute");
658
659                 fontAttrib.size = size;
660                 fontAttrib.style = 0;
661                 fontAttrib.style |= (style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
662                 fontAttrib.style |= (style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
663
664                 rtn = pFont->SetAttrib(fontAttrib);
665                 SysTryReturnResult(NID_GRP, rtn, E_SYSTEM, "Failed to set font attribute");
666         }
667
668         //--------------------------------------------------------------------------
669         // step 3
670         //
671         // add newly created font resource to rsrc manager
672         //--------------------------------------------------------------------------
673         rtn = __AddFont(systemFontNameTemp, sharedFont);
674         SysTryReturnResult(NID_GRP, rtn, E_SYSTEM, "Failed to add font resource into the shared container");
675
676         // set
677         out = sharedFont;
678
679         //--------------------------------------------------------------------------
680         // step 4
681         //
682         // remove unused font
683         //--------------------------------------------------------------------------
684         __RemoveUnusedFont();
685
686         return E_SUCCESS;
687 }
688
689 result
690 _FontRsrcManager::GetSystemFont(const Tizen::Base::String& fontName, int style, _Util::FixedPoint26_6 size, SharedFontResource& out)
691 {
692         FcPattern *pFontPattern = null;
693         FcFontSet *pFontSet = null;
694         FcResult res = FcResultNoMatch;
695         FcChar8* pPath = null;
696         const char* fcStyle = (style & FONT_STYLE_BOLD) ? "Bold" : "Regular";
697         result r = E_SYSTEM;
698
699         ByteBuffer* pBuffer = StringUtil::StringToUtf8N(fontName);
700         if (pBuffer == null)
701         {
702                 return E_SYSTEM;
703         }
704         std::auto_ptr<ByteBuffer> utfString(pBuffer);
705
706         //FcBool rtn = FcInitReinitialize();
707         //SysTryCatch(NID_GRP, rtn != FcFalse, , r, "[E_SYSTEM] Failed to init fontconfig");
708
709         pFontPattern = FcPatternBuild(NULL, FC_STYLE, FcTypeString, (FcChar8*)fcStyle, NULL);
710         SysTryCatch(NID_GRP, pFontPattern, , r, "[E_SYSTEM] Failed to FcPatternBuild()");
711
712         FcPatternAddString(pFontPattern, FC_FAMILY, (FcChar8*)utfString->GetPointer());
713         FcConfigSubstitute(NULL, pFontPattern, FcMatchPattern);
714         FcDefaultSubstitute(pFontPattern);
715
716         pFontSet = FcFontSort(NULL, pFontPattern, FcTrue, NULL, &res);
717         SysTryCatch(NID_GRP, pFontSet, , r, "[E_SYSTEM] Failed to FcFontSort()");
718
719         res = FcPatternGetString(pFontSet->fonts[0], FC_FILE, 0, &pPath);
720         SysTryCatch(NID_GRP, res == FcResultMatch, , r, "[E_SYSTEM] Failed to get path of system font");
721
722         r = this->GetFont(String((char*)pPath), style, size, out);
723         SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Failed to get font", GetErrorMessage(r));
724
725         // destroy
726         FcPatternDestroy(pFontPattern);
727         FcFontSetDestroy(pFontSet);
728         //FcFini();
729
730         return E_SUCCESS;
731
732 CATCH:
733         if (pFontSet)
734         {
735                 FcFontSetDestroy(pFontSet);
736         }
737
738         if (pFontPattern)
739         {
740                 FcPatternDestroy(pFontPattern);
741         }
742
743         //FcFini();
744
745         return r;
746 }
747
748 void
749 _FontRsrcManager::__InitFontRsrcManager(void)
750 {
751         static _FontRsrcManager instance;
752         __pTheInstance = &instance;
753 }
754
755 _FontRsrcManager&
756 _FontRsrcManager::GetInstance(void)
757 {
758         static pthread_once_t once_block = PTHREAD_ONCE_INIT;
759
760         if (!__pTheInstance)
761         {
762                 pthread_once(&once_block, __InitFontRsrcManager);
763         }
764
765         return (*__pTheInstance);
766 }
767
768 bool
769 _FontRsrcManager::__CreateFont(int fontEngine, const void* pBuffer, long bufSize, long face, _IFont** ppOut)
770 {
771         // check input param
772         SysTryReturn(NID_GRP, ppOut, false, E_INVALID_ARG, "[E_INVALID_ARG] Invalid out param is given");
773
774         std::auto_ptr<_IFont> autoPtrFont;
775
776         switch (fontEngine)
777         {
778         case 0:
779                 autoPtrFont.reset(new (std::nothrow) _FontFt2);
780                 break;
781
782         default:
783                 autoPtrFont.reset(new (std::nothrow) _FontNull);
784                 break;
785         }
786
787         SysTryReturn(NID_GRP, autoPtrFont.get() != null, false, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory");
788
789         bool rtn = autoPtrFont->Create(pBuffer, bufSize, face);
790         SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to create font resource");
791
792         // set out param
793         *ppOut = autoPtrFont.release();
794
795         return true;
796 }
797
798 bool
799 _FontRsrcManager::__CreateFont(int fontEngine, const char* filePath, const long face, _IFont** ppOut)
800 {
801         // check input param
802         SysTryReturn(NID_GRP, ppOut, false, E_INVALID_ARG, "[E_INVALID_ARG] Invalid out param is given");
803
804         std::auto_ptr<_IFont> autoPtrFont;
805
806         switch (fontEngine)
807         {
808         case 0:
809                 autoPtrFont.reset(new (std::nothrow) _FontFt2);
810                 break;
811
812         default:
813                 autoPtrFont.reset(new (std::nothrow) _FontNull);
814                 break;
815         }
816
817         SysTryReturn(NID_GRP, autoPtrFont.get() != null, false, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory");
818
819         bool rtn = autoPtrFont->Create(filePath, face);
820         SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to create font resource");
821
822         // set out param
823         *ppOut = autoPtrFont.release();
824
825         return true;
826 }
827
828 bool
829 _FontRsrcManager::__CreateStaticFont(int fontEngine, const void* pBuffer, long bufSize, long face, _IFont** ppOut)
830 {
831         // check input param
832         SysTryReturn(NID_GRP, ppOut, false, E_INVALID_ARG, "[E_INVALID_ARG] Invalid out param is given");
833
834         std::auto_ptr<_IFont> autoPtrFont;
835
836         switch (fontEngine)
837         {
838         case 0:
839                 autoPtrFont.reset(new (std::nothrow) _FontFt2);
840                 break;
841
842         default:
843                 autoPtrFont.reset(new (std::nothrow) _FontNull);
844                 break;
845         }
846
847         SysTryReturn(NID_GRP, autoPtrFont.get() != null, false, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory");
848
849         bool rtn = autoPtrFont->CreateStatic(pBuffer, bufSize, face);
850         SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to create font resource");
851
852         // set out param
853         *ppOut = autoPtrFont.release();
854
855         return true;
856 }
857
858 bool
859 _FontRsrcManager::__SearchFont(const _Util::WString& fontPath, SharedFontResource& out) const
860 {
861         // check input param
862         SysTryReturn(NID_GRP, out.get() == null, false, E_INVALID_ARG, "[E_INVALID_ARG] Invalid out param is given");
863
864 #ifdef USE_HASHMAP_FOR_FONT
865         return (__fontRsrcMap.GetValue(fontPath, out) == E_SUCCESS);
866 #else
867         FontMapT::const_iterator fontIterator = __fontRsrcMap.find(fontPath);
868
869         if (fontIterator != __fontRsrcMap.end())
870         {
871                 out = fontIterator->second;
872                 return true;
873         }
874
875         return false;
876 #endif
877 }
878
879 bool
880 _FontRsrcManager::__AddFont(const _Util::WString& key, const SharedFontResource& font)
881 {
882         // check input param
883         SysTryReturn(NID_GRP, font.get() != null, false, E_INVALID_ARG, "[E_INVALID_ARG] Invalid input param is given");
884
885 #ifdef USE_HASHMAP_FOR_FONT
886         result r = __fontRsrcMap.Add(key, font);
887
888         SysTryReturn(NID_GRP, r == E_SUCCESS || r == E_OBJ_ALREADY_EXIST, false, false, "[%s] Failed to add font into resource pool", GetErrorMessage(r));
889 #else
890         __fontRsrcMap[key] = font;
891 #endif
892
893         return true;
894 }
895
896 void
897 _FontRsrcManager::__RemoveUnusedFont(void)
898 {
899         ArrayListT<_Util::WString> keys;
900         String systemFontName(_DEFAULT_SYSTEM_FONT);
901         String systemBoldFontName(_DEFAULT_SYSTEM_BOLD_FONT);
902
903         _Util::WString systemFontNameTemp(systemFontName.GetPointer());
904         _Util::WString systemBoldFontNameTemp(systemBoldFontName.GetPointer());
905
906         // find out unused font
907
908 #ifdef USE_HASHMAP_FOR_FONT
909         {
910                 std::auto_ptr<IMapEnumeratorT<_Util::WString, SharedFontResource> > enumerator(__fontRsrcMap.GetMapEnumeratorN());
911                 result r = GetLastResult();
912                 SysTryReturnVoidResult(NID_GRP, enumerator.get() != null, r, "[%s] Propagating.", GetErrorMessage(r));
913
914                 while (enumerator->MoveNext() == E_SUCCESS)
915                 {
916                         SharedFontResource font;
917                         r = enumerator->GetValue(font);
918
919                         if (r == E_SUCCESS && font.use_count() == 2)
920                         {
921                                 _Util::WString key(L"");
922                                 r = enumerator->GetKey(key);
923
924                                 if (r == E_SUCCESS && (key != systemFontNameTemp && key != systemBoldFontNameTemp))
925                                 {
926                                         keys.Add(key);
927                                 }
928                         }
929                 }
930         }
931 #else
932         {
933                 for (FontMapT::iterator fontIterator = __fontRsrcMap.begin(); fontIterator != __fontRsrcMap.end(); ++fontIterator)
934                 {
935                         SharedFontResource font(fontIterator->second);
936
937                         if (font != null && font.use_count() == 2)
938                         {
939                                 _Util::WString key(fontIterator->first);
940
941                                 if (key != systemFontNameTemp && key != systemBoldFontNameTemp)
942                                 {
943                                         keys.Add(key);
944                                 }
945                         }
946                 }
947         }
948 #endif
949
950         // remove
951         if (keys.GetCount() > 0)
952         {
953                 std::auto_ptr<IEnumeratorT<_Util::WString> > enumerator(keys.GetEnumeratorN());
954                 result r = GetLastResult();
955                 SysTryReturnVoidResult(NID_GRP, enumerator.get() != null, r, "[%s] Propagating.", GetErrorMessage(r));
956
957                 while (enumerator->MoveNext() == E_SUCCESS)
958                 {
959                         _Util::WString key(L"");
960                         r = enumerator->GetCurrent(key);
961
962                         if (r == E_SUCCESS)
963                         {
964 #ifdef USE_HASHMAP_FOR_FONT
965                                 __fontRsrcMap.Remove(key);
966 #else
967                                 __fontRsrcMap.erase(key);
968 #endif
969                         }
970                 }
971         }
972
973         return;
974 }
975
976 bool
977 _FontRsrcManager::__ReloadFont(String fontName, bool isBold)
978 {
979         SharedFontResource sharedFont;
980         _Util::WString systemFontName(fontName.GetPointer());
981
982         _IFont* pFont = null;
983         bool rtn = false;
984
985         // Check if there is default system font in font resource manager
986         // If there isn't default system font, we can't reload font resource
987         rtn = __SearchFont(systemFontName, sharedFont);
988         SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to search default system font");
989
990         // Get default system font interface instance
991         pFont = sharedFont.get();
992
993         // Reload system font resource in font interface
994         {
995 #ifdef USE_MMAP
996                 isBold ? __defaultSystemBoldFontPath.Clear() : __defaultSystemFontPath.Clear();
997                 const String& fontPath = __GetDefaultSystemFontPath(isBold);
998
999                 ByteBuffer* pBuffer = StringUtil::StringToUtf8N(fontPath);
1000                 if (pBuffer == null)
1001                 {
1002                         return false;
1003                 }
1004                 std::auto_ptr<ByteBuffer> pathString(pBuffer);
1005
1006                 rtn = pFont->Reload((char*)pathString->GetPointer(), _DEFAULT_FONT_FACE);
1007                 SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to reload font");
1008 #else
1009                 int fileLength = 0;
1010                 File file;
1011
1012                 isBold ? __defaultSystemBoldFontPath.Clear() : __defaultSystemFontPath.Clear();
1013
1014                 result r = file.Construct(__GetDefaultSystemFontPath(isBold), L"rb");
1015                 SysTryReturn(NID_GRP, r == E_SUCCESS, false, r, "[%s] Failed to open file", GetErrorMessage(r));
1016
1017                 r = file.Seek(FILESEEKPOSITION_END, 0);
1018                 SysTryReturn(NID_GRP, r == E_SUCCESS, false, r, "[%s] Failed to seek file", GetErrorMessage(r));
1019
1020                 fileLength = file.Tell();
1021                 SysTryReturn(NID_GRP, fileLength > 0, false, r, "[%s] The length of the file is not positive", GetErrorMessage(r));
1022
1023                 r = file.Seek(FILESEEKPOSITION_BEGIN, 0);
1024                 SysTryReturn(NID_GRP, r == E_SUCCESS, false, r, "[%s] Failed to seek file", GetErrorMessage(r));
1025
1026                 std::unique_ptr<unsigned char[]> autoPtrBuffer(new (std::nothrow) unsigned char[fileLength]);
1027                 SysTryReturn(NID_GRP, autoPtrBuffer, false, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to create buffer of the file length");
1028
1029                 file.Read(autoPtrBuffer.get(), fileLength);
1030                 rtn = pFont->Reload(autoPtrBuffer.get(), fileLength, _DEFAULT_FONT_FACE);
1031                 SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to reload font");
1032 #endif
1033
1034                 pFont->CleanCache();
1035         }
1036
1037         return true;
1038 }
1039
1040 bool
1041 _FontRsrcManager::ReloadDefaultSystemFont(void)
1042 {
1043         // reinitialize fontconfig library
1044         FcInitReinitialize();
1045
1046         String systemFontName;
1047
1048         systemFontName = _DEFAULT_SYSTEM_FONT;
1049         __ReloadFont(systemFontName, false);
1050
1051         systemFontName = _DEFAULT_SYSTEM_BOLD_FONT;
1052         __ReloadFont(systemFontName, true);
1053
1054         return true;
1055 }
1056
1057 _FontMemoryManager&
1058 _FontRsrcManager::GetMemoryManager(void)
1059 {
1060         return *__pFontMemoryManager;
1061 }
1062
1063
1064 _Font&
1065 _FontRsrcManager::GetDefaultSystemFont(void)
1066 {
1067         if (__pDefaultSystemFont == null)
1068         {
1069                 std::auto_ptr<_Font> font(new (std::nothrow) _Font);
1070
1071                 if (font.get())
1072                 {
1073                         result r = font->Construct(FONT_STYLE_PLAIN, _SYSTEM_DEFAULT_FONT_SIZE);
1074
1075                         if (r == E_SUCCESS)
1076                         {
1077                                 __pDefaultSystemFont = font.release();
1078                         }
1079                 }
1080         }
1081
1082         SysAssert(__pDefaultSystemFont != null);
1083
1084         return *__pDefaultSystemFont;
1085 }
1086
1087
1088 long
1089 _FontRsrcManager::__GetMaxFontEngine(void) const
1090 {
1091         return 1;
1092 }
1093
1094 String
1095 _FontRsrcManager::__GetFontPath(bool isBold)
1096 {
1097         String fontPath(L"");
1098
1099         FcFontSet* pFontSet = null;
1100         FcPattern* pFontPattern = null;
1101         const char* fcStyle = isBold ? "Bold" : "Regular";
1102         // initialize fontconfig library
1103         //FcBool rtn = FcInitReinitialize();
1104         //SysTryCatch(NID_GRP, rtn != FcFalse, , E_SYSTEM, "[E_SYSTEM] Failed to init fontconfig");
1105
1106         // create pattern
1107         pFontPattern = FcPatternCreate();
1108         SysTryCatch(NID_GRP, pFontPattern, , E_SYSTEM, "[E_SYSTEM] Failed to create font pattern");
1109
1110         FcPatternAddString(pFontPattern, FC_FAMILY, (FcChar8*)"Tizen");
1111         FcPatternAddString(pFontPattern, FC_STYLE, (FcChar8*)fcStyle);
1112         FcConfigSubstitute(0, pFontPattern, FcMatchPattern);
1113         FcDefaultSubstitute(pFontPattern);
1114
1115         // create fontset
1116         pFontSet = FcFontSetCreate();
1117         SysTryCatch(NID_GRP, pFontSet, , E_SYSTEM, "[E_SYSTEM] Failed to create fontset");
1118
1119         {
1120                 FcPattern* pMatchedPattern = null;
1121                 FcResult result = FcResultNoMatch;
1122                 pMatchedPattern = FcFontMatch(NULL, pFontPattern, &result);
1123
1124                 if (/*result == FcResultMatch && */pMatchedPattern)
1125                 {
1126                         FcFontSetAdd(pFontSet, pMatchedPattern);
1127                 }
1128
1129                 // check if we have a system font info
1130                 SysTryCatch(NID_GRP, pFontSet->nfont >= 1, , E_SYSTEM, "[E_SYSTEM] Default system count is %d", pFontSet->nfont);
1131
1132                 FcChar8* pPath = null;
1133                 result = FcPatternGetString(pFontSet->fonts[0], FC_FILE, 0, &pPath);
1134                 SysTryCatch(NID_GRP, result == FcResultMatch, , E_SYSTEM, "[E_SYSTEM] Failed to create fontset");
1135                 fontPath.Clear();
1136                 fontPath.Append(String((char*)pPath));
1137         }
1138
1139         // destroy
1140         FcPatternDestroy(pFontPattern);
1141         FcFontSetDestroy(pFontSet);
1142         //FcFini();
1143
1144         return fontPath;
1145
1146 CATCH:
1147         if (pFontSet != null)
1148         {
1149                 FcFontSetDestroy(pFontSet);
1150         }
1151
1152         if (pFontPattern != null)
1153         {
1154                 FcPatternDestroy(pFontPattern);
1155         }
1156
1157         return fontPath;
1158 }
1159
1160 const String&
1161 _FontRsrcManager::__GetDefaultSystemFontPath(bool isBold)
1162 {
1163         String& defaultPath = (isBold) ? __defaultSystemBoldFontPath : __defaultSystemFontPath;
1164
1165         if (!defaultPath.IsEmpty())
1166         {
1167                 return defaultPath;
1168         }
1169         else
1170         {
1171                 String path = __GetFontPath(isBold);
1172
1173                 if (isBold)
1174                 {
1175                         if (path.IsEmpty())
1176                         {
1177                                 path = __GetFontPath(false);
1178                                 // [ykahn] Is 'path' always not NULL ?
1179                         }
1180
1181                         __defaultSystemBoldFontPath.Clear();
1182                         __defaultSystemBoldFontPath.Append(path);
1183
1184                         return __defaultSystemBoldFontPath;
1185                 }
1186                 else
1187                 {
1188                         __defaultSystemFontPath.Clear();
1189                         __defaultSystemFontPath.Append(path);
1190
1191                         return __defaultSystemFontPath;
1192                 }
1193         }
1194 }
1195
1196 bool
1197 _FontRsrcManager::RemoveMemory(unsigned long requestedSize)
1198 {
1199 #ifdef USE_REMOVE_ALL_CACHE
1200
1201 #ifdef USE_HASHMAP_FOR_FONT
1202         result r = E_SUCCESS;
1203         std::auto_ptr<IMapEnumeratorT<_Util::WString, SharedFontResource > > enumerator(__fontRsrcMap.GetMapEnumeratorN());
1204
1205         while (enumerator->MoveNext() == E_SUCCESS)
1206         {
1207                 SharedFontResource fontRsrc;
1208                 r = enumerator->GetValue(fontRsrc);
1209
1210                 fontRsrc.get()->CleanCache();
1211         }
1212
1213         return true;
1214 #else
1215         for (FontMapT::iterator fontIterator = __fontRsrcMap.begin(); fontIterator != __fontRsrcMap.end(); ++fontIterator)
1216         {
1217                 SharedFontResource fontRsrc(fontIterator->second);
1218
1219                 fontRsrc.get()->CleanCache();
1220         }
1221
1222         return true;
1223 #endif
1224
1225 #else
1226         unsigned long remainedMemory = 0;
1227         result r = E_SUCCESS;
1228         bool isComplete = false;
1229
1230         ArrayListT<String> keys;
1231         String systemFontName(_DEFAULT_SYSTEM_FONT);
1232         _Util::WString systemFontNameTemp(systemFontName.GetPointer());
1233
1234         std::auto_ptr<IMapEnumeratorT<_Util::WString, SharedFontResource > > enumerator(__fontRsrcMap.GetMapEnumeratorN());
1235
1236         while (enumerator->MoveNext() == E_SUCCESS)
1237         {
1238                 if (isComplete)
1239                 {
1240                         break;
1241                 }
1242
1243                 _Util::WString key;
1244                 r = enumerator->GetKey(key);
1245                 if (r == E_SUCCESS/* && key != systemFontNameTemp*/)
1246                 {
1247                         SharedFontResource fontRsrc;
1248                         r = enumerator->GetValue(fontRsrc);
1249
1250                         while (!fontRsrc.get()->second->IsEmpty())
1251                         {
1252                                 fontRsrc.get()->second->RemoveFirst();
1253
1254                                 remainedMemory = __pFontMemoryManager->GetRemainedMemory();
1255
1256                                 if (remainedMemory > requestedSize)
1257                                 {
1258                                                 isComplete = true;
1259                                                 break;
1260                                 }
1261                         }
1262                 }
1263         }
1264
1265         return isComplete;
1266 #endif
1267 }
1268
1269 Tizen::Base::String
1270 _FontRsrcManager::FindAppFontName(const Tizen::Base::String& fontName)
1271 {
1272         String fontPath(L"");
1273
1274         if (__isAppFontListInitialized)
1275         {
1276                 __appFontMap.GetValue(fontName, fontPath);
1277
1278                 return fontPath;
1279         }
1280         else
1281         {
1282                 String dirName;
1283                 Directory dir;
1284                 DirEnumerator* pDirEnum;
1285
1286                 //dirName = L"/usr/share/app_font";
1287                 dirName = Tizen::App::App::GetInstance()->GetAppResourcePath() + L"font";
1288
1289                 // Open the directory
1290                 if (IsFailed(dir.Construct(dirName)))
1291                 {
1292                         return fontPath;
1293                 }
1294
1295                 // Reads all the directory entries
1296                 pDirEnum = dir.ReadN();
1297
1298                 if (!pDirEnum)
1299                 {
1300                         return fontPath;
1301                 }
1302
1303                 // Loops through all the directory entries
1304                 while (pDirEnum->MoveNext() == E_SUCCESS)
1305                 {
1306                         SharedFontResource sharedFont;
1307                         String faceName;
1308                         String name;
1309                         String token;
1310                         DirEntry entry = pDirEnum->GetCurrentDirEntry();
1311                         Tizen::Base::Utility::StringTokenizer formatTok(entry.GetName(), L".");
1312
1313                         while (formatTok.GetTokenCount())
1314                         {
1315                                 formatTok.GetNextToken(token);
1316                         }
1317
1318                         if (entry.IsDirectory() == false)
1319                         {
1320                                 name.Append(dirName);
1321                                 name.Append(L"/");
1322                                 name.Append(entry.GetName());
1323
1324                                 faceName = _Font::GetFaceName(name);
1325
1326                                 __appFontMap.Add(faceName, name);
1327                         }
1328                 }
1329
1330                 delete pDirEnum;
1331                 pDirEnum = null;
1332
1333                 __isAppFontListInitialized = true;
1334
1335                 __appFontMap.GetValue(fontName, fontPath);
1336
1337                 return fontPath;
1338         }
1339 }
1340
1341 }} // Tizen::Graphics