2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.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
9 // http://www.apache.org/licenses/LICENSE-2.0/
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.
20 * @brief This is the implementation file for _Font class.
24 #include "FGrp_Font.h"
25 #include "FGrp_FontFt2.h"
27 #include <unique_ptr.h>
30 #include <fontconfig/fontconfig.h>
31 #include <pango/pangocairo.h>
32 #include <unicode/uloc.h>
34 #include <FApp_AppInfo.h>
36 #include <FBaseByteBuffer.h>
37 #include <FBaseColArrayList.h>
38 #include <FBaseColIList.h>
39 #include <FBaseUtilStringUtil.h>
40 #include <FGrpDimension.h>
41 #include <FGrpPoint.h>
42 #include <FGrpRectangle.h>
44 #include <FBaseSysLog.h>
45 #include <FSys_EnvironmentImpl.h>
46 #include <FIoDirectory.h>
48 #include "FGrp_FontImpl.h"
50 #include "FGrp_CanvasRasterOp.h"
51 #include "FGrp_FontRsrcManager.h"
52 #include "FGrp_FontBidiUtil.h"
54 #include "FGrp_Canvas.h"
56 #include "util/FGrp_UtilTemplate.h"
58 //#define USE_FONTCONFIG
60 #define SYNCHRONIZATION_2_0
61 #define __pNativeFont __sharedFont.get()
63 #define GET_FONT_SIZE_PROPERTY(sizeProperty, rtnValue) \
65 bool rtn = __pNativeFont->GetFontSizeProperty(sizeProperty); \
66 SysTryReturn(NID_GRP, rtn, rtnValue, E_SYSTEM, "[E_SYSTEM] Failed to get font size property"); \
68 #define GET_FONT_PROPERTY(property, rtnValue) \
70 bool rtn = __pNativeFont->GetFontProperty(property); \
71 SysTryReturn(NID_GRP, rtn, rtnValue, E_SYSTEM, "[E_SYSTEM] Failed to get font property"); \
73 #define LOAD_GLYPH_DATA_CONST(character, pFontGlyphData, rtnValue) \
75 _Font* pThis = const_cast <_Font*>(this); \
76 bool rtn = pThis->LoadGlyph(character, &pFontGlyphData); \
77 SysTryReturn(NID_GRP, rtn, rtnValue, E_SYSTEM, "[E_SYSTEM] Failed to load glyph data"); \
79 #define UNLOAD_GLYPH_DATA_CONST(pFontGlyphData) \
81 _Font* pThis = const_cast <_Font*>(this); \
82 pThis->UnloadGlyph(&pFontGlyphData); \
84 #define APPLY_ATTRIBUTE(rtnValue) \
86 _Font* pFont = const_cast <_Font*>(this); \
87 bool rtn = pFont->ApplyAttribute(); \
88 SysTryReturn(NID_GRP, rtn, rtnValue, E_SYSTEM, "[E_SYSTEM] Failed to apply font attribute"); \
90 #define SAMPLE_LANGUAGE_EMPTY ""
93 using namespace Tizen::Base;
94 using namespace Tizen::Base::Collection;
95 using namespace Tizen::Base::Utility;
96 using namespace Tizen::Graphics;
97 using namespace Tizen::Io;
98 using namespace Tizen::System;
103 const _Util::FixedPoint26_6 _SYSTEM_DEFAULT_FONT_SIZE(16);
105 template<typename Type>
107 _ExpandBounds(Type curX, Type curY, Type& x1, Type& y1, Type& x2, Type& y2)
131 _GetSystemFontList(Tizen::Base::Collection::IList& list)
133 #ifdef USE_FONTCONFIG
134 FcPattern* pPattern = null;
135 FcFontSet* pSet = null;
136 FcObjectSet* pObjectSet = null;
137 const char* pLang = null;
138 const char* fcStyle = "Regular";
140 // initialize fontconfig library
141 FcBool rtn = FcInit();
142 SysTryCatch(NID_GRP, rtn, , E_SYSTEM, "[E_SYSTEM] Failed to init fontconfig");
144 pPattern = FcPatternCreate();
145 SysTryCatch(NID_GRP, pPattern, , E_SYSTEM, "[E_SYSTEM] Failed to FcPatternCreate()");
147 // language and style
148 FcPatternAddString(pPattern, FC_STYLE, (FcChar8*)fcStyle);
150 // RFC3066 formatted 2-level language identifier will be returned.
151 // e.g., en-NR, ar-SD, byn, tig etc.
152 // but, fontconfig only need 1-level language identifier having maximum 3 letters.
153 pLang = uloc_getDefault();
157 char lang3Letters[4] = {0,};
158 strncpy(lang3Letters, pLang, 3);
160 for (int i = 0; i < 3; i++)
162 if (lang3Letters[i] == '-' || lang3Letters[i] == '_')
169 FcPatternAddString(pPattern, FC_LANG, (FcChar8*)lang3Letters);
172 pObjectSet = FcObjectSetBuild(FC_FAMILY, FC_STYLE, FC_FILE, NULL);
173 SysTryCatch(NID_GRP, pObjectSet, , E_SYSTEM, "[E_SYSTEM] Failed to FcObjectSetBuild()");
175 pSet = FcFontList(NULL, pPattern, pObjectSet);
176 SysTryCatch(NID_GRP, pSet, , E_SYSTEM, "[E_SYSTEM] Failed to init fontconfig");
179 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
180 String defaultFontFaceName(mgr.GetDefaultSystemFont().GetFaceName());
182 bool defaultFontExists = false;
184 list.RemoveAll(true);
185 FcChar8* pName = null;
187 for (int i = 0; i < pSet->nfont; i++)
189 if (FcPatternGetString(pSet->fonts[i], FC_FILE, 0, &pName) == FcResultMatch)
191 String* pFamilyName = new (std::nothrow) String(Tizen::Graphics::_Font::GetFaceName(String((char*)pName)));
192 SysTryCatch(NID_GRP, pFamilyName, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocated memory");
194 list.Add(*pFamilyName);
196 if (*pFamilyName == defaultFontFaceName)
198 defaultFontExists = true;
203 if (defaultFontExists == false)
205 String* pDefaultFontName = new (std::nothrow) String(defaultFontFaceName);
206 SysTryCatch(NID_GRP, pDefaultFontName, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocated memory");
208 list.InsertAt(*pDefaultFontName, 0);
213 FcFontSetDestroy(pSet);
214 FcObjectSetDestroy(pObjectSet);
215 FcPatternDestroy(pPattern);
221 list.RemoveAll(true);
223 // destroy, but before doing that check if those value has been created or not.
226 FcFontSetDestroy(pSet);
231 FcObjectSetDestroy(pObjectSet);
236 FcPatternDestroy(pPattern);
241 return GetLastResult();
244 const String FONT_DIR_PATH[] =
246 // L"/usr/share/fallback_fonts",
250 list.RemoveAll(true);
252 const int FONT_DIR_PATH_COUNT = sizeof(FONT_DIR_PATH) / sizeof(FONT_DIR_PATH[0]);
254 for (int i = 0; i < FONT_DIR_PATH_COUNT; i++)
258 result r = directory.Construct(FONT_DIR_PATH[i]);
262 std::auto_ptr<DirEnumerator> dirEnumerator(directory.ReadN());
264 while (dirEnumerator->MoveNext() == E_SUCCESS)
266 DirEntry entry = dirEnumerator->GetCurrentDirEntry();
268 if (entry.IsDirectory() == false && entry.IsHidden() == false)
270 Tizen::Base::Utility::StringTokenizer formatTok(entry.GetName(), ".");
273 while (formatTok.GetTokenCount())
275 formatTok.GetNextToken(token);
278 if (token.Equals("ttf",false) || token.Equals("ttc",false))
281 fullName.Append(FONT_DIR_PATH[i]);
282 fullName.Append(L"/");
283 fullName.Append(entry.GetName());
285 bool isNewFont = true;
287 String* pFamilyName = new (std::nothrow) String(Tizen::Graphics::_Font::GetFaceName(fullName));
288 SysTryCatch(NID_GRP, pFamilyName, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocated memory");
290 for (int idx = 0; idx < list.GetCount(); idx++)
292 String* pName = static_cast <String*>(list.GetAt(idx));
299 if (*pName == *pFamilyName)
308 list.Add(*pFamilyName);
324 list.RemoveAll(true);
326 return GetLastResult();
331 typedef Tizen::Graphics::_Font::SystemPixel _SystemPixel;
332 typedef Tizen::Graphics::_Util::ScratchPad<_SystemPixel> _ScratchPad32;
336 _ComposeColor(unsigned long color32, int opacity)
338 unsigned char alpha = (unsigned char) (((color32) >> 24));
339 unsigned char red = (unsigned char) (((color32) >> 16));
340 unsigned char green = (unsigned char) (((color32) >> 8));
341 unsigned char blue = (unsigned char) ((color32));
343 alpha = (unsigned char) ((alpha * opacity + 255) >> 8);
344 red = (unsigned char) ((red * opacity + 255) >> 8);
345 green = (unsigned char) ((green * opacity + 255) >> 8);
346 blue = (unsigned char) ((blue * opacity + 255) >> 8);
348 return (unsigned long) (((unsigned long) (alpha) << 24) | ((unsigned long) (red) << 16) | ((unsigned long) (green) << 8) | (unsigned long) (blue));
352 _SetColor(cairo_t* pCairo, unsigned long composedColor)
354 double a = ((composedColor >> 24) & 0xFF) * 1.0 / 255.0;
355 double r = ((composedColor >> 16) & 0xFF) * 1.0 / 255.0;
356 double g = ((composedColor >> 8) & 0xFF) * 1.0 / 255.0;
357 double b = ((composedColor >> 0) & 0xFF) * 1.0 / 255.0;
359 cairo_set_source_rgba(pCairo, r, g, b, a);
366 return (a < b) ? a : b;
368 #define BLEND_ALPHA_COMPONEMT(srcA, dstA) (_TempMin <unsigned long>((srcA) + (dstA) - (((srcA) * (dstA)) >> 8), 0xFF));
370 struct _NativeGfxEngine
373 cairo_surface_t* pCairoSurface;
384 cairo_destroy(pCairo);
389 cairo_surface_destroy(pCairoSurface);
396 const char* _SampleLanguages[] =
398 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_COMMON
399 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_INHERITED
400 "ar", // G_UNICODE_SCRIPT_ARABIC
401 "hy", // G_UNICODE_SCRIPT_ARMENIAN
402 "bn", // G_UNICODE_SCRIPT_BENGALI
403 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_BOPOMOFO
404 "chr", // G_UNICODE_SCRIPT_CHEROKEE
405 "cop", // G_UNICODE_SCRIPT_COPTIC
406 "ru", // G_UNICODE_SCRIPT_CYRILLIC
407 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_DESERET
408 "hi", // G_UNICODE_SCRIPT_DEVANAGARI
409 "am", // G_UNICODE_SCRIPT_ETHIOPIC
410 "ka", // G_UNICODE_SCRIPT_GEORGIAN
411 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_GOTHIC
412 "el", // G_UNICODE_SCRIPT_GREEK
413 "gu", // G_UNICODE_SCRIPT_GUJARATI
414 "pa", // G_UNICODE_SCRIPT_GURMUKHI
415 "zh", // G_UNICODE_SCRIPT_HAN
416 "ko", // G_UNICODE_SCRIPT_HANGUL
417 "he", // G_UNICODE_SCRIPT_HEBREW
418 "ja", // G_UNICODE_SCRIPT_HIRAGANA
419 "kn", // G_UNICODE_SCRIPT_KANNADA
420 "ja", // G_UNICODE_SCRIPT_KATAKANA
421 "km", // G_UNICODE_SCRIPT_KHMER
422 "lo", // G_UNICODE_SCRIPT_LAO
423 "en", // G_UNICODE_SCRIPT_LATIN
424 "ml", // G_UNICODE_SCRIPT_MALAYALAM
425 "mn", // G_UNICODE_SCRIPT_MONGOLIAN
426 "my", // G_UNICODE_SCRIPT_MYANMAR
427 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_OGHAM
428 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_OLD_ITALIC
429 "or", // G_UNICODE_SCRIPT_ORIYA
430 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_RUNIC
431 "si", // G_UNICODE_SCRIPT_SINHALA
432 "syr", // G_UNICODE_SCRIPT_SYRIAC
433 "ta", // G_UNICODE_SCRIPT_TAMIL
434 "te", // G_UNICODE_SCRIPT_TELUGU
435 "dv", // G_UNICODE_SCRIPT_THAANA
436 "th", // G_UNICODE_SCRIPT_THAI
437 "bo", // G_UNICODE_SCRIPT_TIBETAN
438 "iu", // G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL
439 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_YI
440 "tl", // G_UNICODE_SCRIPT_TAGALOG
441 "hnn", // G_UNICODE_SCRIPT_HANUNOO
442 "bku", // G_UNICODE_SCRIPT_BUHID
443 "tbw", // G_UNICODE_SCRIPT_TAGBANWA
444 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_BRAILLE
445 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_CYPRIOT
446 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_LIMBU
447 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_OSMANYA
448 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_SHAVIAN
449 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_LINEAR_B
450 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_TAI_LE
451 "uga", // G_UNICODE_SCRIPT_UGARITIC
452 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_NEW_TAI_LUE
453 "bug", // G_UNICODE_SCRIPT_BUGINESE
454 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_GLAGOLITIC
455 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_TIFINAGH
456 "syl", // G_UNICODE_SCRIPT_SYLOTI_NAGRI
457 "peo", // G_UNICODE_SCRIPT_OLD_PERSIAN
458 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_KHAROSHTHI
459 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_UNKNOWN
460 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_BALINESE
461 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_CUNEIFORM
462 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_PHOENICIAN
463 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_PHAGS_PA
464 "nqo" // G_UNICODE_SCRIPT_NKO
467 const int _sampleLanguageCount = sizeof(_SampleLanguages) / sizeof(_SampleLanguages[0]);
470 GetPredefinedColor(const wchar_t unicode, unsigned long fgColor)
474 // Emoji Unicode List 176 + 76
476 static const unsigned long _EMOJI_BLACK = 0xFF000000;
477 static const unsigned long _EMOJI_BLUE = 0xFF0000FF;
478 static const unsigned long _EMOJI_GREEN = 0xFF00FF00;
479 static const unsigned long _EMOJI_RED = 0xFFFF0000;
480 static const unsigned long _EMOJI_ORANGE = 0xFFFF6600;
481 static const unsigned long _EMOJI_PURPLE = 0xFF9370DB;
482 static const unsigned long _EMOJI_DEEP_PURPLE = 0xFF800080;
483 static const unsigned long _EMOJI_DARK_BLUE = 0xFF00008B;
484 static const unsigned long _EMOJI_BROWN = 0xFFA52A2A;
485 static const unsigned long _NOT_EMOJI = 0;
487 static const wchar_t _MAX_EMOJI_UNICODE = 0xE757;
488 static const wchar_t _MIN_EMOJI_UNICODE = 0xE63E;
490 static const unsigned long _emojiTable[] =
492 _EMOJI_RED, _EMOJI_BLUE, _EMOJI_BLUE, _EMOJI_BLUE, _EMOJI_ORANGE, _EMOJI_RED, _EMOJI_BLUE, _EMOJI_BLUE, _EMOJI_RED, _EMOJI_ORANGE,
493 _EMOJI_GREEN, _EMOJI_BLUE, _EMOJI_RED, _EMOJI_ORANGE, _EMOJI_GREEN, _EMOJI_BLUE, _EMOJI_RED, _EMOJI_ORANGE, _EMOJI_GREEN, _EMOJI_BLUE,
494 _EMOJI_PURPLE, _EMOJI_BLACK, _EMOJI_BLUE, _EMOJI_GREEN, _EMOJI_BLACK, _EMOJI_BLUE, _EMOJI_ORANGE, _EMOJI_BLACK, _EMOJI_PURPLE, _EMOJI_GREEN,
495 _EMOJI_ORANGE, _EMOJI_BLUE, _EMOJI_BLACK, _EMOJI_GREEN, _EMOJI_RED, _EMOJI_BLUE, _EMOJI_BLUE, _EMOJI_RED, _EMOJI_BLUE, _EMOJI_RED,
496 _EMOJI_BLACK, _EMOJI_PURPLE, _EMOJI_RED, _EMOJI_GREEN, _EMOJI_BLUE, _EMOJI_PURPLE, _EMOJI_BLUE, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK,
497 _EMOJI_GREEN, _EMOJI_PURPLE, _EMOJI_ORANGE, _EMOJI_ORANGE, _EMOJI_RED, _EMOJI_BLUE, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_ORANGE,
498 _EMOJI_BLUE, _EMOJI_PURPLE, _EMOJI_BLACK, _EMOJI_RED, _EMOJI_ORANGE, _EMOJI_BLACK, _EMOJI_RED, _EMOJI_BLACK, _EMOJI_RED, _EMOJI_ORANGE,
499 _EMOJI_RED, _EMOJI_RED, _EMOJI_RED, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_ORANGE, _EMOJI_BLUE, _EMOJI_BLACK, _EMOJI_BLUE, _EMOJI_RED,
500 _EMOJI_BLACK, _EMOJI_RED, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_ORANGE, _EMOJI_ORANGE, _EMOJI_ORANGE, _EMOJI_ORANGE, _EMOJI_BLACK, _EMOJI_BLACK,
501 _EMOJI_ORANGE, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLUE, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_ORANGE,
502 _EMOJI_ORANGE, _EMOJI_BLUE, _EMOJI_GREEN, _EMOJI_BLACK, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI,
503 _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _NOT_EMOJI, _NOT_EMOJI, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _NOT_EMOJI, _NOT_EMOJI,
504 _NOT_EMOJI, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI,
505 _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI,
506 _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_ORANGE, _EMOJI_ORANGE, _EMOJI_BLACK,
507 _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_RED, _EMOJI_RED, _EMOJI_RED, _EMOJI_RED, _EMOJI_RED, _EMOJI_RED, _EMOJI_BLUE, _EMOJI_RED,
508 _EMOJI_RED, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK,
509 _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_RED, _EMOJI_RED, _EMOJI_RED, _EMOJI_RED, _EMOJI_PURPLE, _EMOJI_RED,
510 _EMOJI_BLUE, _EMOJI_GREEN, _EMOJI_BLUE, _EMOJI_RED, _EMOJI_RED, _EMOJI_RED, _EMOJI_PURPLE, _EMOJI_RED, _EMOJI_ORANGE, _EMOJI_ORANGE,
511 _EMOJI_BLACK, _EMOJI_RED, _EMOJI_BLACK, _EMOJI_RED, _EMOJI_BLUE, _EMOJI_BLUE, _EMOJI_RED, _EMOJI_PURPLE, _EMOJI_RED, _EMOJI_RED,
512 _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_RED, _EMOJI_ORANGE, _EMOJI_ORANGE, _EMOJI_BLUE, _EMOJI_BLACK,
513 _EMOJI_RED, _EMOJI_DARK_BLUE, _EMOJI_BLUE, _EMOJI_ORANGE, _EMOJI_BROWN, _EMOJI_BROWN, _EMOJI_BLACK, _EMOJI_RED, _EMOJI_BLACK, _EMOJI_GREEN,
514 _EMOJI_ORANGE, _EMOJI_PURPLE, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_GREEN, _EMOJI_BLACK, _EMOJI_GREEN, _EMOJI_PURPLE, _EMOJI_BLUE, _EMOJI_BLUE,
515 _EMOJI_RED, _EMOJI_DEEP_PURPLE, _EMOJI_PURPLE, _EMOJI_ORANGE, _EMOJI_RED, _EMOJI_PURPLE, _EMOJI_PURPLE, _EMOJI_DARK_BLUE, _EMOJI_ORANGE, _EMOJI_BLUE,
516 _EMOJI_BLUE, _EMOJI_RED, _EMOJI_BLUE, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_RED, _EMOJI_GREEN, _EMOJI_BLACK, _EMOJI_ORANGE,
517 _EMOJI_RED, _EMOJI_BLUE, _EMOJI_RED, _EMOJI_RED, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_GREEN, _EMOJI_BLUE, _EMOJI_BLUE, _EMOJI_GREEN,
518 _EMOJI_RED, _EMOJI_RED, _EMOJI_ORANGE, _EMOJI_RED, _EMOJI_GREEN, _EMOJI_RED, _EMOJI_PURPLE, _EMOJI_BLACK, _EMOJI_RED, _EMOJI_BROWN,
519 _EMOJI_ORANGE, _EMOJI_BROWN, _EMOJI_BROWN, _EMOJI_ORANGE, _EMOJI_DARK_BLUE, _EMOJI_BLUE, _EMOJI_ORANGE, _EMOJI_ORANGE, _EMOJI_BROWN, _EMOJI_ORANGE,
520 _EMOJI_DEEP_PURPLE, _EMOJI_DEEP_PURPLE
523 if (unicode >= _MIN_EMOJI_UNICODE && unicode <= _MAX_EMOJI_UNICODE)
525 if (_emojiTable[unicode - _MIN_EMOJI_UNICODE] != _NOT_EMOJI)
527 fgColor = _emojiTable[unicode - _MIN_EMOJI_UNICODE];
537 _Util::String textFragment;
540 _TextFragment(const _Util::String& string, _IFont* pFont)
541 : textFragment(string)
550 namespace Tizen { namespace Graphics
558 _Font::_Font(const _Font& obj)
560 this->__fontAttrib = obj.__fontAttrib;
561 this->__sharedFont = obj.__sharedFont;
571 _Font::Construct(int style, _Util::FixedPoint26_6 pcSize)
573 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
575 // use default system font
576 _FontRsrcManager::SharedFontResource out;
577 result r = mgr.GetFont(style, pcSize, out);
578 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get system default font", GetErrorMessage(r));
582 __UpdateFontAttribute(style, pcSize);
588 _Font::Construct(const Tizen::Base::String& fontName, int style, _Util::FixedPoint26_6 pcSize, bool isPathEnabled)
590 bool systemFont = false;
591 String appFontPath = L"";
592 result r = E_SUCCESS;
594 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
595 _FontRsrcManager::SharedFontResource out;
597 if (!Tizen::App::_AppInfo::IsOspCompat())
599 _Util::WString fontNameTemp(fontName.GetPointer());
600 _Util::WString appFontPathTemp(mgr.FindAppFontName(fontNameTemp));
601 appFontPath.Append(appFontPathTemp.c_str());
604 // check if user want to use a app font
605 if (!appFontPath.IsEmpty())
607 r = mgr.GetFont(appFontPath, style, pcSize, out);
608 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get app font", GetErrorMessage(r));
612 IList* pList = GetSystemFontListN();
617 for (idx = 0; idx < pList->GetCount(); idx++)
619 String* pName = static_cast <String*>(pList->GetAt(idx));
626 if (*pName == fontName)
633 pList->RemoveAll(true);
639 r = mgr.GetSystemFont(fontName, style, pcSize, out);
640 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get system font", GetErrorMessage(r));
642 else if (isPathEnabled)
644 r = mgr.GetFont(fontName, style, pcSize, out);
645 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get font", GetErrorMessage(r));
651 __UpdateFontAttribute(style, pcSize);
657 _Font::Construct(const Tizen::Base::ByteBuffer& fontData, int style, _Util::FixedPoint26_6 pcSize)
659 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
661 const byte* pBuffer = fontData.GetPointer();
662 int buffSize = fontData.GetLimit();
664 _FontRsrcManager::SharedFontResource out;
665 result r = mgr.GetFont(pBuffer, buffSize, style, pcSize, out);
666 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get system font", GetErrorMessage(r));
670 __UpdateFontAttribute(style, pcSize);
676 _Font::IsConstructed(void) const
678 return (__sharedFont.get() != null);
681 _Util::FixedPoint26_6
682 _Font::GetMaxHeight(void) const
684 return __fontAttrib.maxHeight;
687 _Util::FixedPoint26_6
688 _Font::GetMaxWidth(void) const
690 return __fontAttrib.maxWidth;
693 _Util::FixedPoint26_6
694 _Font::GetAscender(void) const
696 return __fontAttrib.ascender;
699 _Util::FixedPoint26_6
700 _Font::GetDescender(void) const
702 return __fontAttrib.descender;
706 _Font::GetLeftBear(wchar_t character, _Util::FixedPoint22_10& leftBear) const
710 _IFont::Glyph* pFontGlyphData = null;
711 LOAD_GLYPH_DATA_CONST(character, pFontGlyphData, E_SYSTEM);
713 // left bear is Glyph::xOffset, set it
714 leftBear = pFontGlyphData->xOffset;
716 UNLOAD_GLYPH_DATA_CONST(pFontGlyphData);
722 _Font::GetRightBear(wchar_t character, _Util::FixedPoint22_10& rightBear) const
726 _IFont::Glyph* pFontGlyphData = null;
727 LOAD_GLYPH_DATA_CONST(character, pFontGlyphData, E_SYSTEM);
729 // right bear is Glyph::xOffset + GlyphBitmap::width, set it
730 rightBear = pFontGlyphData->xOffset + _Util::FixedPoint22_10(pFontGlyphData->image.width);
732 UNLOAD_GLYPH_DATA_CONST(pFontGlyphData);
738 _Font::IsBold(void) const
740 return ((__fontAttrib.style & FONT_STYLE_BOLD) ? true : false);
744 _Font::IsItalic(void) const
746 return ((__fontAttrib.style & FONT_STYLE_ITALIC) ? true : false);
750 _Font::IsPlain(void) const
752 return ((__fontAttrib.style & FONT_STYLE_PLAIN) ? true : false);
756 _Font::IsStrikeOut(void) const
758 return __fontAttrib.strikeout;
762 _Font::IsUnderlined(void) const
764 return __fontAttrib.underline;
767 _Util::FixedPoint26_6
768 _Font::GetSize(void) const
770 return __fontAttrib.size;
774 _Font::SetStrikeOut(bool strikeout)
776 __fontAttrib.strikeout = strikeout;
780 _Font::SetUnderline(bool underline)
782 __fontAttrib.underline = underline;
786 _Font::SetCharSpace(int pc_space)
788 __fontAttrib.charSpace = pc_space;
792 _Font::GetCharSpace(void) const
794 return __fontAttrib.charSpace;
798 _Font::GetLineThickness(void) const
800 return __fontAttrib.lineThickness;
804 _Font::GetFaceName(void) const
806 _IFont::Property property;
807 GET_FONT_PROPERTY(property, String());
809 return ((property.pFamilyName) ? String(property.pFamilyName) : String());
812 Tizen::Base::Collection::IList*
813 _Font::GetSystemFontListN(void)
815 std::auto_ptr<ArrayList> pList(new (std::nothrow) Tizen::Base::Collection::ArrayList);
816 SysTryReturn(NID_GRP, pList.get(), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Fails to allocate memory");
818 result r = _GetSystemFontList(*pList);
819 SysTryReturn(NID_GRP, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
821 return pList.release();
826 _Font::GetFaceName(const Tizen::Base::String& filePath)
828 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
829 _FontRsrcManager::SharedFontResource out;
832 result r = mgr.GetTempFont(filePath, FONT_STYLE_PLAIN, _SYSTEM_DEFAULT_FONT_SIZE, out);
833 SysTryReturn(NID_GRP, r == E_SUCCESS, faceName, r, "[%s] Failed to get font", GetErrorMessage(r));
837 _IFont* pTempFont = out.get();
839 _IFont::Property property;
840 pTempFont->GetFontProperty(property);
841 faceName = String(property.pFamilyName);
848 _Font::GetNativeFont(void) const
850 return __pNativeFont;
857 _Font* pNativeFont = new (std::nothrow) _Font(*this);
858 SysTryReturn(NID_GRP, pNativeFont, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocated memory");
865 _Font::ApplyAttribute()
867 _IFont::Attrib fontAttrib;
868 bool rtn = __pNativeFont->GetAttrib(fontAttrib);
869 SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to get font attribute");
871 fontAttrib.size = __fontAttrib.size;
872 fontAttrib.style = _IFont::STYLE_NONE;
873 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
874 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
875 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
876 rtn = __pNativeFont->SetAttrib(fontAttrib);
877 SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to set font attribute");
883 _Font::GetTextExtent(int width, const _Util::String& text, bool outline, int& count, Dimension& pcDim) const
885 if (text.pStart == null || text.length <= 0)
892 _TextBidiPropertyWithReorder bidiProperty(text.pStart, text.length);
894 if (bidiProperty.HasBidi())
896 typedef _Util::AccumList<_Util::Pair<int, int> > GapList;
900 result r = this->__GetTextExtentList(bidiProperty, gapList);
909 int determinedCount = -1;
911 for (GapList::Iterator i = gapList.Begin(); i != gapList.End(); ++i)
913 left = (i->first < left) ? i->first : left;
914 right = (i->second > right) ? i->second : right;
916 if (determinedCount < 0 && i->first < width && i->second >= width)
918 if (i != gapList.Begin())
920 if (i - gapList.Begin() - 1 < text.length)
922 determinedCount = bidiProperty.pBidiIndex[i - gapList.Begin() - 1];
926 determinedCount = text.length;
931 determinedCount = bidiProperty.pBidiIndex[0];
936 if (right - left <= width)
938 pcDim.SetSize(right - left, __fontAttrib.size.ToInt());
941 else if (determinedCount > 0 && right - left > 0)
943 int expectedValue = width * text.length / (right - left);
944 int tolerance = _Util::Abs(expectedValue - determinedCount);
945 tolerance = (tolerance == 0) ? 2 : tolerance;
947 int tempCount = expectedValue <= determinedCount ? determinedCount + tolerance : determinedCount + (tolerance * 2);
948 tempCount = tempCount > text.length ? text.length : tempCount;
952 while (right - left > width)
954 _TextBidiPropertyWithReorder determinedBidiProperty(text.pStart, --tempCount);
956 GapList determinedGapList;
958 result r = this->__GetTextExtentList(determinedBidiProperty, determinedGapList);
968 for (GapList::Iterator i = determinedGapList.Begin(); i != determinedGapList.End(); ++i)
970 left = (i->first < left) ? i->first : left;
971 right = (i->second > right) ? i->second : right;
975 pcDim.SetSize(right - left, __fontAttrib.size.ToInt());
988 return this->__GetTextExtent(width, text, outline, count, pcDim);
995 _Font::__GetTextExtent(int width, const _Util::String& text, bool outline, int& count, Dimension& pcDim) const
997 if (text.pStart == null)
1000 SysTryReturn(NID_GRP, false, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The given string is invalid.");
1003 int preX1 = 0x7FFFFFFF;
1004 int preY1 = 0x7FFFFFFF;
1005 int preX2 = -0x7FFFFFFF;
1006 int preY2 = -0x7FFFFFFF;
1008 int x1 = 0x7FFFFFFF;
1009 int y1 = 0x7FFFFFFF;
1010 int x2 = -0x7FFFFFFF;
1011 int y2 = -0x7FFFFFFF;
1017 int italicSpace = 0;
1023 wchar_t leftChar = 0;
1025 _IFont::Glyph* pFontGlyphData = 0;
1027 if (text.length == 0)
1030 pcDim.SetSize(0, 0);
1034 _Font* pThis = const_cast <_Font*>(this);
1036 APPLY_ATTRIBUTE(E_SYSTEM);
1039 _IFont::SizeProperty sizeProperty;
1040 GET_FONT_SIZE_PROPERTY(sizeProperty, E_SYSTEM);
1042 if (__fontAttrib.style & FONT_STYLE_ITALIC)
1044 italicSpace = (sizeProperty.ascender.ToInt() * 2) >> 4;
1048 if (__fontAttrib.style & FONT_STYLE_BOLD)
1050 _IFont::Attrib attr;
1051 pThis->GetAttrib(attr);
1052 boldSpace = static_cast<int>(attr.boldWeight.ToFloat() + 0.5f);
1055 const wchar_t* pText = text.pStart;
1056 int length = text.length;
1058 while (*pText && --length >= 0)
1060 // getting proper _Font instance for the specified text
1061 _IFont* pFont = pThis->__GetFont(*pText);
1063 if (pFont != __pNativeFont)
1065 _IFont::Attrib fontAttrib;
1066 bool rtn = pFont->GetAttrib(fontAttrib);
1067 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to get font attribute");
1069 fontAttrib.size = __fontAttrib.size;
1070 fontAttrib.style = _IFont::STYLE_NONE;
1071 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
1072 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
1073 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
1074 rtn = pFont->SetAttrib(fontAttrib);
1075 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to set font attribute");
1080 if (pFont->GetKerning(leftChar, *pText, xVec, yVec))
1086 if (pFont->LoadGlyph(*pText++, &pFontGlyphData))
1088 int glyphBoundX1 = curX;
1089 int glyphBoundY1 = curY - pFontGlyphData->yOffset.ToInt();
1090 int glyphBoundX2 = glyphBoundX1 +
1091 ((pFontGlyphData->image.width <= 0) ? pFontGlyphData->xAdvance.ToInt()
1092 : (pFontGlyphData->xOffset.ToInt() + pFontGlyphData->image.width));
1093 int glyphBoundY2 = glyphBoundY1 + pFontGlyphData->image.height;
1095 #ifdef SYNCHRONIZATION_2_0
1096 // adjusting x2 bounds for synchronizing fuctionality with 2.0
1097 glyphBoundX2 = glyphBoundX1 + pFontGlyphData->xAdvance.ToInt() + italicSpace + boldSpace;
1107 _ExpandBounds(glyphBoundX1, glyphBoundY1, x1, y1, x2, y2);
1108 _ExpandBounds(glyphBoundX2, glyphBoundY1, x1, y1, x2, y2);
1109 _ExpandBounds(glyphBoundX1, glyphBoundY2, x1, y1, x2, y2);
1110 _ExpandBounds(glyphBoundX2, glyphBoundY2, x1, y1, x2, y2);
1112 #ifdef SYNCHRONIZATION_2_0
1113 curX += pFontGlyphData->xAdvance.ToInt() + __fontAttrib.charSpace + italicSpace + boldSpace;
1115 curX += pFontGlyphData->xAdvance.ToInt() + __fontAttrib.charSpace + boldSpace;
1117 curY += pFontGlyphData->yAdvance.ToInt();
1119 pFont->UnloadGlyph(&pFontGlyphData);
1121 // check end condition
1122 // TODO, shkim, BIDI need to be cared
1123 if ((x2 - x1) > width)
1134 leftChar = *(pText - 1);
1138 if (characters == 0)
1140 pcDim.SetSize(0, 0);
1145 SysTryCatch(NID_GRP, preX1 <= preX2 && preY1 <= preY2, pcDim.SetSize(0, 0); count = 0, E_SYSTEM, "[E_SYSTEM] Failed to calculate text extent");
1148 pcDim.width = preX2 - preX1;
1149 #ifdef SYNCHRONIZATION_2_0
1150 pcDim.height = __fontAttrib.size.ToInt();
1152 pcDim.height = preY2 - preY1;
1153 #endif // SYNCHRONIZATION_2_0
1162 _Font::GetTextExtent(int width, const _Util::String& text, bool outline, const Tizen::Base::String& delimiter, int& count, Dimension& dim) const
1164 const wchar_t* pText = text.pStart;
1165 const wchar_t* pTextEnd = pText + text.length;
1167 while (pText < pTextEnd)
1169 if (*pText == 0x0D || *pText == 0x0A)
1178 return this->GetTextExtent(width, _Util::String(text.pStart, pTextEnd - text.pStart), outline, count, dim);
1182 _Font::__GetTextExtentList(const _Util::String& text, _Util::AccumList<_Util::Pair<int, int> >& outList) const
1184 SysAssert(text.pStart != null && text.length > 0);
1188 _Font* pThis = const_cast <_Font*>(this);
1190 APPLY_ATTRIBUTE(E_SYSTEM);
1192 int addingSpace = __fontAttrib.charSpace;
1194 #ifdef SYNCHRONIZATION_2_0
1196 _IFont::SizeProperty sizeProperty;
1198 GET_FONT_SIZE_PROPERTY(sizeProperty, E_SYSTEM);
1200 if (__fontAttrib.style & FONT_STYLE_ITALIC)
1202 addingSpace += (sizeProperty.ascender.ToInt() * 2) >> 4;
1207 if (__fontAttrib.style & FONT_STYLE_BOLD)
1209 _IFont::Attrib attr;
1211 if (pThis->GetAttrib(attr))
1213 addingSpace += static_cast<int>(attr.boldWeight.ToFloat() + 0.5f);
1219 wchar_t prevChar = 0;
1221 const wchar_t* pText = text.pStart;
1222 int length = text.length;
1226 while (*(++pText) && --length >= 0)
1228 _IFont* pFont = pThis->__GetFont(*pText);
1232 if (pFont != __pNativeFont)
1234 _IFont::Attrib fontAttrib;
1236 if (pFont->GetAttrib(fontAttrib))
1238 fontAttrib.size = __fontAttrib.size;
1239 fontAttrib.style = _IFont::STYLE_NONE;
1240 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
1241 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
1242 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
1243 pFont->SetAttrib(fontAttrib);
1247 _IFont::Glyph* pFontGlyphData = 0;
1249 if (pFont->LoadGlyph(*pText, &pFontGlyphData))
1251 // When LoadGlyph fails continuously in the original code, there is a problem to check the kerning on the results of the previous prevChar
1257 if (pFont->GetKerning(prevChar, *pText, xVec, yVec))
1265 curX += pFontGlyphData->xAdvance.ToInt() + addingSpace;
1266 curY += pFontGlyphData->yAdvance.ToInt();
1268 pFont->UnloadGlyph(&pFontGlyphData);
1271 outList.Push(_Util::MakePair(prevX, curX));
1277 // Cannot determine a glyph extent
1279 outList.Push(_Util::MakePair(curX, curX));
1286 _Font::__GetTextExtentList(_TextBidiPropertyWithReorder& bidiProperty, _Util::AccumList<_Util::Pair<int, int> >& outList) const
1288 if (bidiProperty.length <= 0)
1295 _Util::AccumList<_Util::Pair<int, int> > tempList;
1301 int length = bidiProperty.length;
1303 _Font* pThis = const_cast <_Font*>(this);
1305 pThis->ApplyAttribute();
1307 const wchar_t* pReorderedText = bidiProperty.GetReorderedText();
1309 const wchar_t* pTextFragmentBegin = pReorderedText;
1310 const wchar_t* pTextFragmentEnd = pTextFragmentBegin + length;
1312 const wchar_t* pTextSegment = pTextFragmentBegin;
1314 _IFont* pBaseFont = pThis->__GetFont(*pTextSegment);
1316 _Util::AccumList<_TextFragment> textFragmentList;
1318 while (pTextSegment < pTextFragmentEnd)
1320 if (pBaseFont->CheckGlyph(*pTextSegment) == 0)
1322 _IFont* pFallbackFont = pThis->__GetFont(*pTextSegment);
1324 if (pBaseFont != pFallbackFont)
1326 textFragmentList.Push(_TextFragment(_Util::String(pTextFragmentBegin, pTextSegment - pTextFragmentBegin), pBaseFont));
1328 pTextFragmentBegin = pTextSegment;
1329 pBaseFont = pFallbackFont;
1336 textFragmentList.Push(_TextFragment(_Util::String(pTextFragmentBegin, pTextSegment - pTextFragmentBegin), pBaseFont));
1340 * for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.Begin(); textFragment != textFragmentList.End(); ++textFragment)
1343 * for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.End(); textFragment != textFragmentList.Begin(); )
1349 for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.Begin(); textFragment != textFragmentList.End(); ++textFragment)
1351 if (textFragment->pUsingFont == null || textFragment->textFragment.length <= 0)
1356 if (textFragment->pUsingFont != __pNativeFont)
1358 _IFont::Attrib fontAttrib;
1360 if (textFragment->pUsingFont->GetAttrib(fontAttrib))
1362 fontAttrib.size = __fontAttrib.size;
1363 fontAttrib.style = _IFont::STYLE_NONE;
1364 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
1365 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
1366 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
1368 textFragment->pUsingFont->SetAttrib(fontAttrib);
1372 Tizen::Base::Collection::ArrayListT<_IFont::Glyph *> glyphList;
1374 const wchar_t firstChar = *textFragment->textFragment.pStart;
1376 GUnicodeScript script = _TextBidiUtil::GetUnicodeScript(firstChar);
1377 // need to check if (script < 0 || script >= _sampleLanguageCount) ?
1379 textFragment->pUsingFont->GetGlyphList(textFragment->textFragment, glyphList, script);
1381 int count = glyphList.GetCount();
1383 for (int i = 0; i < count; i++)
1385 _IFont::Glyph *pGlyph = 0;
1387 glyphList.GetAt(i, pGlyph);
1389 // bug fixed in test case of L"\x9a8\x20\x981\x9a0\x635"
1390 //if (pGlyph->xAdvance == 0 && pGlyph->image.width == 0)
1397 xDest += pGlyph->xAdvance.ToInt();
1398 yDest += pGlyph->yAdvance.ToInt();
1400 tempList.Push(_Util::MakePair(prevX, xDest));
1401 outList.Push(_Util::MakePair(-1, -1));
1404 IEnumeratorT<_IFont::Glyph*>* pEnum = glyphList.GetEnumeratorN();
1408 while (pEnum->MoveNext() == E_SUCCESS)
1410 _IFont::Glyph* pGlyph;
1412 pEnum->GetCurrent(pGlyph);
1413 pBaseFont->UnloadGlyph(&pGlyph);
1421 if (bidiProperty.pBidiIndex)
1423 // Reorder list by using BIDI index
1424 typedef _Util::Pair<int, int> Gap;
1425 typedef _Util::AccumList<Gap> GapList;
1427 GapList::Iterator dstBegin = outList.Begin();
1431 if (bidiProperty.length == int(tempList.Size()))
1433 for (GapList::ConstIterator src = tempList.Begin(); src != tempList.End(); ++src)
1435 *(dstBegin + bidiProperty.pBidiIndex[index++]) = *src;
1438 else if (bidiProperty.length > int(tempList.Size()))
1440 _TextBidiUtil::GetReorderedIndexList(bidiProperty, tempList, outList);
1442 else // if (bidiProperty.length < tempList.Size())
1444 // under development
1445 for (GapList::ConstIterator src = tempList.Begin(); src != tempList.End() && index < bidiProperty.length; ++src)
1447 *(dstBegin + bidiProperty.pBidiIndex[index++]) = *src;
1453 typedef _Util::Pair<int, int> Gap;
1454 typedef _Util::AccumList<Gap> GapList;
1456 GapList::Iterator dst = outList.Begin();
1457 GapList::Iterator dstEnd = outList.End();
1459 GapList::ConstIterator src = tempList.Begin();
1460 GapList::ConstIterator srcEnd = tempList.End();
1462 for (; (src != srcEnd) && (dst != dstEnd); ++src, ++dst)
1472 _Font::GetTextExtentList(const _Util::String& text, _Util::AccumList<_Util::Pair<int, int> >& outList) const
1474 if (text.pStart == null || text.length <= 0)
1480 _TextBidiPropertyWithReorder bidiProperty(text.pStart, text.length);
1482 if (bidiProperty.HasBidi())
1484 return this->__GetTextExtentList(bidiProperty, outList);
1488 return this->__GetTextExtentList(text, outList);
1495 _Font::SetSize(_Util::FixedPoint26_6 pcSize)
1497 __UpdateFontAttribute(__fontAttrib.style, pcSize);
1503 _Font::SetStyle(int style)
1505 __fontAttrib.style = style;
1511 _Font::GetStyle(void) const
1513 return __fontAttrib.style;
1516 _Util::FixedPoint26_6
1517 _Font::GetLeading(void) const
1519 return __fontAttrib.maxHeight;
1523 _Font::__DrawText(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length)
1525 SysTryReturnResult(NID_GRP, canvas.__pScratchPad != null, E_INVALID_ARG, "A canvas is invalid");
1527 const wchar_t* pText = text.GetPointer() + startIndex;
1529 bool rtn = this->ApplyAttribute();
1530 SysTryReturn(NID_GRP, rtn, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fails to apply font attribute.");
1532 _Util::ScratchPad <SystemPixel>& scratchPad = *canvas.__pScratchPad;
1533 scratchPad.RegisterFillRect(_RasterOp::FnFillRectFont32Bit);
1535 Rectangle clipBounds;
1536 canvas.__GetClipBounds(clipBounds);
1538 int xDest = point.x;
1539 int yDest = point.y;
1540 int startX = point.x;
1542 int italicSpace = 0;
1544 int clipX1 = clipBounds.x;
1545 int clipY1 = clipBounds.y;
1546 int clipX2 = clipX1 + clipBounds.width;
1547 int clipY2 = clipY1 + clipBounds.height;
1551 wchar_t leftChar = 0;
1552 _IFont::Glyph* pFontGlyphData = 0;
1554 // need to revise y value, because _IFont is based on the baseline
1556 _IFont::SizeProperty sizeProperty;
1557 bool rtn = this->GetFontSizeProperty(sizeProperty);
1558 SysTryReturn(NID_GRP, rtn, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to get font sizeProperty.");
1560 if (canvas.__textOrigin == TEXT_ORIGIN_LEFT_TOP)
1562 yDest += sizeProperty.maxHeight.ToInt() + sizeProperty.descender.ToInt();
1565 charHeight = sizeProperty.ascender.ToInt() - sizeProperty.descender.ToInt();
1567 if (this->GetStyle() & FONT_STYLE_ITALIC)
1569 italicSpace = (sizeProperty.ascender.ToInt() * 2) >> 4;
1573 if (this->GetStyle() & FONT_STYLE_BOLD)
1575 _IFont::Attrib attr;
1576 this->GetAttrib(attr);
1577 boldSpace = static_cast<int>(attr.boldWeight.ToFloat() + 0.5f);
1580 unsigned long canvasFgColor = canvas.__fgColor;
1582 _TextBidiPropertyWithReorder bidiProperty(pText, length);
1584 if (bidiProperty.HasBidi())
1586 const wchar_t* pReorderedText = bidiProperty.GetReorderedText();
1588 const wchar_t* pTextFragmentBegin = pReorderedText;
1589 const wchar_t* pTextFragmentEnd = pTextFragmentBegin + length;
1591 const wchar_t* pTextSegment = pTextFragmentBegin;
1593 _IFont* pBaseFont = this->__GetFont(*pTextSegment);
1595 _Util::AccumList<_TextFragment> textFragmentList;
1597 while (pTextSegment < pTextFragmentEnd)
1599 if (pBaseFont->CheckGlyph(*pTextSegment) == 0)
1601 _IFont* pFallbackFont = this->__GetFont(*pTextSegment);
1603 if (pBaseFont != pFallbackFont)
1605 textFragmentList.Push(_TextFragment(_Util::String(pTextFragmentBegin, pTextSegment - pTextFragmentBegin), pBaseFont));
1607 pTextFragmentBegin = pTextSegment;
1608 pBaseFont = pFallbackFont;
1615 textFragmentList.Push(_TextFragment(_Util::String(pTextFragmentBegin, pTextSegment - pTextFragmentBegin), pBaseFont));
1619 * for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.Begin(); textFragment != textFragmentList.End(); ++textFragment)
1622 * for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.End(); textFragment != textFragmentList.Begin(); )
1628 for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.Begin(); textFragment != textFragmentList.End(); ++textFragment)
1630 if (textFragment->pUsingFont == null || textFragment->textFragment.length <= 0)
1635 if (textFragment->pUsingFont != __pNativeFont)
1637 _IFont::Attrib fontAttrib;
1639 if (textFragment->pUsingFont->GetAttrib(fontAttrib))
1641 fontAttrib.size = __fontAttrib.size;
1642 fontAttrib.style = _IFont::STYLE_NONE;
1643 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
1644 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
1645 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
1647 textFragment->pUsingFont->SetAttrib(fontAttrib);
1651 Tizen::Base::Collection::ArrayListT<_IFont::Glyph *> glyphList;
1653 const wchar_t firstChar = *textFragment->textFragment.pStart;
1655 GUnicodeScript script = _TextBidiUtil::GetUnicodeScript(firstChar);
1657 textFragment->pUsingFont->GetGlyphList(textFragment->textFragment, glyphList, script);
1658 // need to check if (script < 0 || script >= _sampleLanguageCount) ?
1660 int count = glyphList.GetCount();
1662 for (int i = 0; i < count; i++)
1665 static int s_index = 0;
1666 const unsigned long COLOR[6] =
1675 unsigned long canvasFgColor = COLOR[s_index++ % 6];
1678 typedef unsigned long TPixel;
1679 _IFont::Glyph *pGlyph = 0;
1681 TPixel srcR, srcG, srcB, srcA;
1682 TPixel dstR, dstG, dstB, dstA;
1684 srcA = (canvasFgColor >> 24) & 0xFF;
1685 srcA += (srcA >> 7);
1686 srcR = (canvasFgColor >> 16) & 0xFF;
1687 srcG = (canvasFgColor >> 8) & 0xFF;
1688 srcB = (canvasFgColor) & 0xFF;
1690 SystemPixel* pBufferStartAddr = null;
1693 scratchPad.GetBuffer(pBufferStartAddr, bufferPitch);
1695 glyphList.GetAt(i, pGlyph);
1697 for (int h = 0; h < pGlyph->image.height; h++)
1699 int y = yDest - pGlyph->yOffset.ToInt() + h;
1711 TPixel* pDest32 = pBufferStartAddr + y * bufferPitch + xDest + pGlyph->xOffset.ToInt();
1713 for (int w = 0; w < pGlyph->image.width; w++)
1715 int x = xDest + pGlyph->xOffset.ToInt() + w;
1728 unsigned long alpha = (unsigned long) (pGlyph->image.pBitmap[h * pGlyph->image.bytesPerLine + w]);
1732 // equivalent to scratchPad.FillRect(x, y, 1, 1, fgColor, alpha);
1733 alpha = (alpha * srcA) >> 8;
1734 alpha += (alpha >> 7);
1736 dstA = (*pDest32 >> 24) & 0xFF;
1737 dstR = (*pDest32 >> 16) & 0xFF;
1738 dstG = (*pDest32 >> 8) & 0xFF;
1739 dstB = (*pDest32) & 0xFF;
1741 dstA = BLEND_ALPHA_COMPONEMT(alpha, dstA);
1742 dstR = (dstR + (((srcR - dstR) * alpha) >> 8)) & 0xFF;
1743 dstG = (dstG + (((srcG - dstG) * alpha) >> 8)) & 0xFF;
1744 dstB = (dstB + (((srcB - dstB) * alpha) >> 8)) & 0xFF;
1746 *pDest32 = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB;
1753 xDest += pGlyph->xAdvance.ToInt();
1754 yDest += pGlyph->yAdvance.ToInt();
1757 scratchPad.RegisterFillRect(null);
1759 IEnumeratorT<_IFont::Glyph*>* pEnum = glyphList.GetEnumeratorN();
1763 while (pEnum->MoveNext() == E_SUCCESS)
1765 _IFont::Glyph* pGlyph;
1767 pEnum->GetCurrent(pGlyph);
1768 pBaseFont->UnloadGlyph(&pGlyph);
1777 while (*pText && --length >= 0)
1779 // find out proper native font
1780 _IFont* pFont = this->__GetFont(*pText);
1787 if (pFont != __pNativeFont)
1789 _IFont::Attrib fontAttrib;
1790 bool rtn = pFont->GetAttrib(fontAttrib);
1791 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to get font attribute");
1793 fontAttrib.size = __fontAttrib.size;
1794 fontAttrib.style = _IFont::STYLE_NONE;
1795 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
1796 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
1797 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
1799 rtn = pFont->SetAttrib(fontAttrib);
1800 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to set font attribute");
1803 _IFont::Property property;
1804 pFont->GetFontProperty(property);
1806 unsigned long fgColor = (canvas.__applyEmoji && pFont->IsEmoji()) ? GetPredefinedColor(*pText, canvasFgColor) : canvasFgColor;
1810 if (pFont->GetKerning(leftChar, *pText, xVec, yVec))
1816 bool rtn = pFont->LoadGlyph(*pText++, &pFontGlyphData);
1823 typedef unsigned long TPixel;
1825 TPixel srcA = (fgColor >> 24) & 0xFF;
1826 srcA += (srcA >> 7);
1828 TPixel srcR = (fgColor >> 16) & 0xFF;
1829 TPixel srcG = (fgColor >> 8) & 0xFF;
1830 TPixel srcB = (fgColor) & 0xFF;
1832 SystemPixel* pBufferStartAddr = null;
1833 int bufferPitch = 0;
1835 scratchPad.GetBuffer(pBufferStartAddr, bufferPitch);
1837 for (int h = 0; h < pFontGlyphData->image.height; h++)
1839 int y = yDest - pFontGlyphData->yOffset.ToInt() + h;
1851 TPixel* pDest32 = pBufferStartAddr + y * bufferPitch + xDest + pFontGlyphData->xOffset.ToInt();
1853 for (int w = 0; w < pFontGlyphData->image.width; w++)
1855 int x = xDest + pFontGlyphData->xOffset.ToInt() + w;
1868 unsigned long alpha = (unsigned long) (pFontGlyphData->image.pBitmap[h * pFontGlyphData->image.bytesPerLine + w]);
1872 // equivalent to scratchPad.FillRect(x, y, 1, 1, fgColor, alpha);
1873 alpha = (alpha * srcA) >> 8;
1874 alpha += (alpha >> 7);
1876 TPixel dstA = (*pDest32 >> 24) & 0xFF;
1877 TPixel dstR = (*pDest32 >> 16) & 0xFF;
1878 TPixel dstG = (*pDest32 >> 8) & 0xFF;
1879 TPixel dstB = (*pDest32) & 0xFF;
1881 dstA = BLEND_ALPHA_COMPONEMT(alpha, dstA);
1882 dstR = (dstR + (((srcR - dstR) * alpha) >> 8)) & 0xFF;
1883 dstG = (dstG + (((srcG - dstG) * alpha) >> 8)) & 0xFF;
1884 dstB = (dstB + (((srcB - dstB) * alpha) >> 8)) & 0xFF;
1886 *pDest32 = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB;
1893 xDest += pFontGlyphData->xAdvance.ToInt() + __fontAttrib.charSpace + italicSpace + boldSpace;
1894 yDest += pFontGlyphData->yAdvance.ToInt();
1896 leftChar = *(pText - 1);
1898 pFont->UnloadGlyph(&pFontGlyphData);
1902 if (this->IsUnderlined() || this->IsStrikeOut())
1904 int y = point.y + charHeight - 1;
1905 int thick = this->GetLineThickness();
1907 xDest -= this->GetCharSpace();
1909 if (this->IsUnderlined())
1911 canvas.FillRectangle(canvasFgColor, Rectangle(startX, y - thick, xDest - startX, thick));
1914 if (this->IsStrikeOut())
1916 y -= charHeight / 2;
1917 canvas.FillRectangle(canvasFgColor, Rectangle(startX, y - thick, xDest - startX, thick));
1921 scratchPad.RegisterFillRect(null);
1927 #undef BLEND_ALPHA_COMPONEMT
1930 _Font::__DrawText(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length, const Color& outlineColor)
1932 unsigned long textColor = canvas.__fgColor;
1933 bool applyEmoji = canvas.__applyEmoji;
1935 //sunmi557.shin: draw border of font
1936 canvas.__fgColor = outlineColor.GetRGB32();
1937 canvas.__applyEmoji = false;
1939 this->__DrawText(canvas, Point(point.x - 1, point.y), text, startIndex, length);
1940 this->__DrawText(canvas, Point(point.x + 1, point.y), text, startIndex, length);
1941 this->__DrawText(canvas, Point(point.x, point.y - 1), text, startIndex, length);
1942 this->__DrawText(canvas, Point(point.x, point.y + 1), text, startIndex, length);
1944 //sunmi557.shin: draw original shape of font
1945 canvas.__applyEmoji = applyEmoji;
1946 canvas.__fgColor = textColor;
1948 this->__DrawText(canvas, point, text, startIndex, length);
1954 _Font::SetAttrib(const _IFont::Attrib& fontAttrib)
1956 return __pNativeFont->SetAttrib(fontAttrib);
1960 _Font::GetAttrib(_IFont::Attrib& fontAttrib) const
1962 return __pNativeFont->GetAttrib(fontAttrib);
1966 _Font::GetKerning(unsigned long character1, unsigned long character2, long& xVector, long& yVector) const
1968 return __pNativeFont->GetKerning(character1, character2, xVector, yVector);
1972 _Font::GetFontSizeProperty(_IFont::SizeProperty& sizeProperty) const
1974 return __pNativeFont->GetFontSizeProperty(sizeProperty);
1978 _Font::LoadGlyph(unsigned long character, _IFont::Glyph** ppFontGlyphData)
1980 // note! we assume that the font attribute has been already applied on _IFont
1983 // if not, loading glyph (character/size/style) and caching it
1984 rtn = __pNativeFont->LoadGlyph(character, ppFontGlyphData);
1985 SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to load glyph data");
1987 // return cached glyph
1992 _Font::UnloadGlyph(_IFont::Glyph** ppFontGlyphData)
1994 return __pNativeFont->UnloadGlyph(ppFontGlyphData);
1998 _Font::CheckGlyph(unsigned long character)
2000 return __pNativeFont->CheckGlyph(character);
2004 _Font::__UpdateFontAttribute(int style, _Util::FixedPoint26_6 pcSize)
2006 __fontAttrib.style = style;
2007 __fontAttrib.size = pcSize;
2008 __fontAttrib.lineThickness = ((pcSize < 24) ? 1 : ((pcSize < 48) ? 2 : 3));
2010 _IFont::SizeProperty sizeProperty;
2011 bool getProperty = false;
2013 if (this->ApplyAttribute())
2015 getProperty = __pNativeFont->GetFontSizeProperty(sizeProperty);
2020 __fontAttrib.maxWidth = sizeProperty.maxWidth;
2021 __fontAttrib.maxHeight = sizeProperty.maxHeight;
2022 __fontAttrib.ascender = sizeProperty.ascender;
2023 __fontAttrib.descender = sizeProperty.descender;
2027 // if failed to get property above, each property should be remained as default: -1
2028 SysLog(NID_GRP, "[] Failed to get font attribute from native font");
2030 __fontAttrib.maxWidth.Reset(0);
2031 __fontAttrib.maxHeight.Reset(0);
2032 __fontAttrib.ascender.Reset(0);
2033 __fontAttrib.descender.Reset(0);
2038 _Font::__DrawTextLastFallback(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length)
2044 _Font::__DrawTextDefault(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length)
2046 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
2047 result r = mgr.GetDefaultSystemFont().__DrawText(canvas, point, text, startIndex, length);
2048 SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Failed to draw default system font", GetErrorMessage(r));
2053 _Font::__DrawTextLastFallback(canvas, point, text, startIndex, length);
2058 _Font::__DrawTextDefault(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length, const Color& outlineColor)
2060 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
2061 result r = mgr.GetDefaultSystemFont().__DrawText(canvas, point, text, startIndex, length, outlineColor);
2062 SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Failed to draw default system font", GetErrorMessage(r));
2067 _Font::__DrawTextLastFallback(canvas, point, text, startIndex, length);
2073 _Font::DrawText(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length)
2075 if (canvas.__pPriorityFont)
2077 return canvas.__pPriorityFont->__DrawText(canvas, point, text, startIndex, length);
2079 else if (canvas.__pFont)
2081 return canvas.__pFont->__DrawText(canvas, point, text, startIndex, length);
2085 return _Font::__DrawTextDefault(canvas, point, text, startIndex, length);
2090 _Font::DrawText(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length, const Color& outlineColor)
2092 if (canvas.__pPriorityFont)
2094 return canvas.__pPriorityFont->__DrawText(canvas, point, text, startIndex, length, outlineColor);
2096 else if (canvas.__pFont)
2098 return canvas.__pFont->__DrawText(canvas, point, text, startIndex, length, outlineColor);
2102 return _Font::__DrawTextDefault(canvas, point, text, startIndex, length, outlineColor);
2109 _Font::GetInstance(_FontImpl& font)
2111 return (&font != null) ? font._pNativeFont : null;
2115 _Font::GetInstance(const _FontImpl& font)
2117 return (&font != null) ? font._pNativeFont : null;
2121 _Font::__GetFont(wchar_t character)
2123 //------------------------------------------------------
2125 // 1. check if this font has a requested glyph
2127 //------------------------------------------------------
2128 unsigned long idx = __pNativeFont->CheckGlyph(character);
2132 return __pNativeFont;
2135 //------------------------------------------------------
2137 // 1-2. check if this glyph is in the fallback list.
2139 //------------------------------------------------------
2140 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
2141 _IFont::FontMapT* pFallbackFontMap = __pNativeFont->GetFallbackMap();
2143 #ifdef USE_HASHMAP_FOR_FONT
2144 std::auto_ptr<IMapEnumeratorT<_Util::WString, _FontRsrcManager::SharedFontResource> > enumerator(pFallbackFontMap->GetMapEnumeratorN());
2146 while (enumerator->MoveNext() == E_SUCCESS)
2148 _FontRsrcManager::SharedFontResource pTempFont;
2150 if (enumerator->GetValue(pTempFont) == E_SUCCESS)
2152 _Util::WString key(L"");
2153 result r = enumerator->GetKey(key);
2157 if (mgr.SearchFont(key))
2159 if (pTempFont.get()->CheckGlyph(character) > 0)
2161 return pTempFont.get();
2166 pFallbackFontMap->Remove(key);
2172 for (_FontRsrcManager::FontMapT::const_iterator fontIterator = pFallbackFontMap->begin(); fontIterator != pFallbackFontMap->end(); ++fontIterator)
2174 if (fontIterator->second != null)
2176 if (fontIterator->second->CheckGlyph(character) > 0)
2178 return fontIterator->second.get();
2184 //------------------------------------------------------
2186 // 2. Get fallback font list via fontconfig
2188 //------------------------------------------------------
2189 Tizen::Base::Collection::ArrayListT<String> fileList;
2190 bool rtn = __GetFallbackFontFileList(character, fileList);
2194 // if failed find out fallback font,
2195 // just use this instance for drawing something for unknown glyph
2196 return __pNativeFont;
2199 //------------------------------------------------------
2201 // 3. try to find a font having a requested glyph
2203 //------------------------------------------------------
2205 _IFont* pFallbackFont = null;
2207 _FontRsrcManager::SharedFontResource out;
2209 int count = fileList.GetCount();
2210 result r = E_FAILURE;
2212 for (int i = 0; i < count; i++)
2214 fileList.GetAt(i, fontName);
2216 if (fontName.IsEmpty())
2221 r = mgr.GetTempFont(fontName, __fontAttrib.style, __fontAttrib.size, out);
2225 unsigned long idx = out.get()->CheckGlyph(character);
2229 _Util::WString fontNameTemp(fontName.GetPointer());
2232 #ifdef USE_HASHMAP_FOR_FONT
2233 r = pFallbackFontMap->Add(fontNameTemp, out);
2235 if (r == E_OBJ_ALREADY_EXIST)
2237 pFallbackFont = out.get();
2241 SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
2243 pFallbackFontMap->push_back(std::make_pair(fontNameTemp, out));
2245 r = mgr.AddFont(fontNameTemp, out);
2246 SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
2248 pFallbackFont = out.get();
2254 return (pFallbackFont != null) ? pFallbackFont : __pNativeFont;
2257 // if failed find out fallback font,
2258 // just use this instance for drawing something for unknown glyph
2259 return __pNativeFont;
2263 _Font::__GetFallbackFontFileList(wchar_t character, Tizen::Base::Collection::IListT<String>& out)
2265 GUnicodeScript script = g_unichar_get_script(character);
2266 if (script < 0 || script >= _sampleLanguageCount)
2271 _IFont::Property property;
2272 const char* pFamilyName = null;
2273 GET_FONT_PROPERTY(property, false);
2275 pFamilyName = property.pFamilyName;
2277 FcPattern* pPattern = null;
2278 FcFontSet* pSet = null;
2279 FcChar8* pName = null;
2280 FcResult res = FcResultNoMatch;
2281 const char* fcStyle = (__fontAttrib.style & FONT_STYLE_BOLD) ? "Bold" : "Regular";
2283 // initialize fontconfig library
2284 FcBool rtn = FcInit();
2285 SysTryCatch(NID_GRP, rtn, , E_SYSTEM, "[E_SYSTEM] Failed to init fontconfig");
2287 // getting fallback font list
2288 pPattern = FcPatternBuild(NULL, FC_STYLE, FcTypeString, (FcChar8*)fcStyle, NULL);
2289 SysTryCatch(NID_GRP, pPattern, , E_SYSTEM, "[E_SYSTEM] Failed to FcPatternBuild()");
2291 FcPatternAddString(pPattern, FC_FAMILY, (FcChar8*) pFamilyName);
2293 if (strncmp(SAMPLE_LANGUAGE_EMPTY, _SampleLanguages[script], strlen(SAMPLE_LANGUAGE_EMPTY) + 1) != 0)
2295 FcPatternAddString(pPattern, FC_LANG, (FcChar8*)_SampleLanguages[script]);
2298 FcConfigSubstitute(NULL, pPattern, FcMatchPattern);
2299 FcDefaultSubstitute(pPattern);
2302 pSet = FcFontSort(NULL, pPattern, FcTrue, NULL, &res);
2303 SysTryCatch(NID_GRP, pSet, , E_SYSTEM, "[E_SYSTEM] Failed to FcFontSort()");
2307 for (int i = 0; i < pSet->nfont; i++)
2309 if (FcPatternGetString(pSet->fonts[i], FC_FILE, 0, &pName) == FcResultMatch)
2311 out.Add(String((char*)pName));
2316 FcFontSetDestroy(pSet);
2317 FcPatternDestroy(pPattern);
2320 return (out.GetCount() > 0) ? true : false;
2325 FcFontSetDestroy(pSet);
2328 if (pPattern != null)
2330 FcPatternDestroy(pPattern);
2339 _Font::UpdateDefaultFont(const String& key)
2343 SysLog(NID_GRP, "Request to change the default font");
2345 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
2347 return mgr.ReloadDefaultSystemFont();
2353 }} // Tizen::Graphics