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);
104 const long _MEDIUM_FONT_BOLD_WEIGHT = 600;
106 template<typename Type>
108 _ExpandBounds(Type curX, Type curY, Type& x1, Type& y1, Type& x2, Type& y2)
132 _GetSystemFontList(Tizen::Base::Collection::IList& list)
134 #ifdef USE_FONTCONFIG
135 FcPattern* pPattern = null;
136 FcFontSet* pSet = null;
137 FcObjectSet* pObjectSet = null;
138 const char* pLang = null;
139 const char* fcStyle = "Regular";
141 pPattern = FcPatternCreate();
142 SysTryCatch(NID_GRP, pPattern, , E_SYSTEM, "[E_SYSTEM] Failed to FcPatternCreate()");
144 // language and style
145 FcPatternAddString(pPattern, FC_STYLE, (FcChar8*)fcStyle);
147 // RFC3066 formatted 2-level language identifier will be returned.
148 // e.g., en-NR, ar-SD, byn, tig etc.
149 // but, fontconfig only need 1-level language identifier having maximum 3 letters.
150 pLang = uloc_getDefault();
154 char lang3Letters[4] = {0,};
155 strncpy(lang3Letters, pLang, 3);
157 for (int i = 0; i < 3; i++)
159 if (lang3Letters[i] == '-' || lang3Letters[i] == '_')
166 FcPatternAddString(pPattern, FC_LANG, (FcChar8*)lang3Letters);
169 pObjectSet = FcObjectSetBuild(FC_FAMILY, FC_STYLE, FC_FILE, NULL);
170 SysTryCatch(NID_GRP, pObjectSet, , E_SYSTEM, "[E_SYSTEM] Failed to FcObjectSetBuild()");
172 pSet = FcFontList(NULL, pPattern, pObjectSet);
173 SysTryCatch(NID_GRP, pSet, , E_SYSTEM, "[E_SYSTEM] Failed to init fontconfig");
176 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
177 String defaultFontFaceName(mgr.GetDefaultSystemFont().GetFaceName());
179 bool defaultFontExists = false;
181 list.RemoveAll(true);
182 FcChar8* pName = null;
184 for (int i = 0; i < pSet->nfont; i++)
186 if (FcPatternGetString(pSet->fonts[i], FC_FILE, 0, &pName) == FcResultMatch)
188 String* pFamilyName = new (std::nothrow) String(Tizen::Graphics::_Font::GetFaceName(String((char*)pName)));
189 SysTryCatch(NID_GRP, pFamilyName, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocated memory");
191 list.Add(*pFamilyName);
193 if (*pFamilyName == defaultFontFaceName)
195 defaultFontExists = true;
200 if (defaultFontExists == false)
202 String* pDefaultFontName = new (std::nothrow) String(defaultFontFaceName);
203 SysTryCatch(NID_GRP, pDefaultFontName, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocated memory");
205 list.InsertAt(*pDefaultFontName, 0);
210 FcFontSetDestroy(pSet);
211 FcObjectSetDestroy(pObjectSet);
212 FcPatternDestroy(pPattern);
217 list.RemoveAll(true);
219 // destroy, but before doing that check if those value has been created or not.
222 FcFontSetDestroy(pSet);
227 FcObjectSetDestroy(pObjectSet);
232 FcPatternDestroy(pPattern);
235 return GetLastResult();
238 const String FONT_DIR_PATH[] =
240 // L"/usr/share/fallback_fonts",
244 list.RemoveAll(true);
246 const int FONT_DIR_PATH_COUNT = sizeof(FONT_DIR_PATH) / sizeof(FONT_DIR_PATH[0]);
248 for (int i = 0; i < FONT_DIR_PATH_COUNT; i++)
252 result r = directory.Construct(FONT_DIR_PATH[i]);
256 std::auto_ptr<DirEnumerator> dirEnumerator(directory.ReadN());
258 while (dirEnumerator->MoveNext() == E_SUCCESS)
260 DirEntry entry = dirEnumerator->GetCurrentDirEntry();
262 if (entry.IsDirectory() == false && entry.IsHidden() == false)
264 Tizen::Base::Utility::StringTokenizer formatTok(entry.GetName(), ".");
267 while (formatTok.GetTokenCount())
269 formatTok.GetNextToken(token);
272 if (token.Equals("ttf",false) || token.Equals("ttc",false))
275 fullName.Append(FONT_DIR_PATH[i]);
276 fullName.Append(L"/");
277 fullName.Append(entry.GetName());
279 bool isNewFont = true;
281 String* pFamilyName = new (std::nothrow) String(Tizen::Graphics::_Font::GetFaceName(fullName));
282 SysTryCatch(NID_GRP, pFamilyName, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocated memory");
284 for (int idx = 0; idx < list.GetCount(); idx++)
286 String* pName = static_cast <String*>(list.GetAt(idx));
293 if (*pName == *pFamilyName)
302 list.Add(*pFamilyName);
318 list.RemoveAll(true);
320 return GetLastResult();
325 typedef Tizen::Graphics::_Font::SystemPixel _SystemPixel;
326 typedef Tizen::Graphics::_Util::ScratchPad<_SystemPixel> _ScratchPad32;
330 _ComposeColor(unsigned long color32, int opacity)
332 unsigned char alpha = (unsigned char) (((color32) >> 24));
333 unsigned char red = (unsigned char) (((color32) >> 16));
334 unsigned char green = (unsigned char) (((color32) >> 8));
335 unsigned char blue = (unsigned char) ((color32));
337 alpha = (unsigned char) ((alpha * opacity + 255) >> 8);
338 red = (unsigned char) ((red * opacity + 255) >> 8);
339 green = (unsigned char) ((green * opacity + 255) >> 8);
340 blue = (unsigned char) ((blue * opacity + 255) >> 8);
342 return (unsigned long) (((unsigned long) (alpha) << 24) | ((unsigned long) (red) << 16) | ((unsigned long) (green) << 8) | (unsigned long) (blue));
346 _SetColor(cairo_t* pCairo, unsigned long composedColor)
348 double a = ((composedColor >> 24) & 0xFF) * 1.0 / 255.0;
349 double r = ((composedColor >> 16) & 0xFF) * 1.0 / 255.0;
350 double g = ((composedColor >> 8) & 0xFF) * 1.0 / 255.0;
351 double b = ((composedColor >> 0) & 0xFF) * 1.0 / 255.0;
353 cairo_set_source_rgba(pCairo, r, g, b, a);
360 return (a < b) ? a : b;
362 #define BLEND_ALPHA_COMPONEMT(srcA, dstA) (_TempMin <unsigned long>((srcA) + (dstA) - (((srcA) * (dstA)) >> 8), 0xFF));
364 struct _NativeGfxEngine
367 cairo_surface_t* pCairoSurface;
378 cairo_destroy(pCairo);
383 cairo_surface_destroy(pCairoSurface);
390 const char* _SampleLanguages[] =
392 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_COMMON
393 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_INHERITED
394 "ar", // G_UNICODE_SCRIPT_ARABIC
395 "hy", // G_UNICODE_SCRIPT_ARMENIAN
396 "bn", // G_UNICODE_SCRIPT_BENGALI
397 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_BOPOMOFO
398 "chr", // G_UNICODE_SCRIPT_CHEROKEE
399 "cop", // G_UNICODE_SCRIPT_COPTIC
400 "ru", // G_UNICODE_SCRIPT_CYRILLIC
401 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_DESERET
402 "hi", // G_UNICODE_SCRIPT_DEVANAGARI
403 "am", // G_UNICODE_SCRIPT_ETHIOPIC
404 "ka", // G_UNICODE_SCRIPT_GEORGIAN
405 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_GOTHIC
406 "el", // G_UNICODE_SCRIPT_GREEK
407 "gu", // G_UNICODE_SCRIPT_GUJARATI
408 "pa", // G_UNICODE_SCRIPT_GURMUKHI
409 "zh", // G_UNICODE_SCRIPT_HAN
410 "ko", // G_UNICODE_SCRIPT_HANGUL
411 "he", // G_UNICODE_SCRIPT_HEBREW
412 "ja", // G_UNICODE_SCRIPT_HIRAGANA
413 "kn", // G_UNICODE_SCRIPT_KANNADA
414 "ja", // G_UNICODE_SCRIPT_KATAKANA
415 "km", // G_UNICODE_SCRIPT_KHMER
416 "lo", // G_UNICODE_SCRIPT_LAO
417 "en", // G_UNICODE_SCRIPT_LATIN
418 "ml", // G_UNICODE_SCRIPT_MALAYALAM
419 "mn", // G_UNICODE_SCRIPT_MONGOLIAN
420 "my", // G_UNICODE_SCRIPT_MYANMAR
421 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_OGHAM
422 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_OLD_ITALIC
423 "or", // G_UNICODE_SCRIPT_ORIYA
424 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_RUNIC
425 "si", // G_UNICODE_SCRIPT_SINHALA
426 "syr", // G_UNICODE_SCRIPT_SYRIAC
427 "ta", // G_UNICODE_SCRIPT_TAMIL
428 "te", // G_UNICODE_SCRIPT_TELUGU
429 "dv", // G_UNICODE_SCRIPT_THAANA
430 "th", // G_UNICODE_SCRIPT_THAI
431 "bo", // G_UNICODE_SCRIPT_TIBETAN
432 "iu", // G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL
433 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_YI
434 "tl", // G_UNICODE_SCRIPT_TAGALOG
435 "hnn", // G_UNICODE_SCRIPT_HANUNOO
436 "bku", // G_UNICODE_SCRIPT_BUHID
437 "tbw", // G_UNICODE_SCRIPT_TAGBANWA
438 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_BRAILLE
439 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_CYPRIOT
440 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_LIMBU
441 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_OSMANYA
442 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_SHAVIAN
443 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_LINEAR_B
444 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_TAI_LE
445 "uga", // G_UNICODE_SCRIPT_UGARITIC
446 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_NEW_TAI_LUE
447 "bug", // G_UNICODE_SCRIPT_BUGINESE
448 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_GLAGOLITIC
449 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_TIFINAGH
450 "syl", // G_UNICODE_SCRIPT_SYLOTI_NAGRI
451 "peo", // G_UNICODE_SCRIPT_OLD_PERSIAN
452 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_KHAROSHTHI
453 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_UNKNOWN
454 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_BALINESE
455 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_CUNEIFORM
456 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_PHOENICIAN
457 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_PHAGS_PA
458 "nqo" // G_UNICODE_SCRIPT_NKO
461 const int _sampleLanguageCount = sizeof(_SampleLanguages) / sizeof(_SampleLanguages[0]);
464 GetPredefinedColor(const wchar_t unicode, unsigned long fgColor)
468 // Emoji Unicode List 176 + 76
470 static const unsigned long _EMOJI_BLACK = 0xFF000000;
471 static const unsigned long _EMOJI_BLUE = 0xFF0000FF;
472 static const unsigned long _EMOJI_GREEN = 0xFF00FF00;
473 static const unsigned long _EMOJI_RED = 0xFFFF0000;
474 static const unsigned long _EMOJI_ORANGE = 0xFFFF6600;
475 static const unsigned long _EMOJI_PURPLE = 0xFF9370DB;
476 static const unsigned long _EMOJI_DEEP_PURPLE = 0xFF800080;
477 static const unsigned long _EMOJI_DARK_BLUE = 0xFF00008B;
478 static const unsigned long _EMOJI_BROWN = 0xFFA52A2A;
479 static const unsigned long _NOT_EMOJI = 0;
481 static const wchar_t _MAX_EMOJI_UNICODE = 0xE757;
482 static const wchar_t _MIN_EMOJI_UNICODE = 0xE63E;
484 static const unsigned long _emojiTable[] =
486 _EMOJI_RED, _EMOJI_BLUE, _EMOJI_BLUE, _EMOJI_BLUE, _EMOJI_ORANGE, _EMOJI_RED, _EMOJI_BLUE, _EMOJI_BLUE, _EMOJI_RED, _EMOJI_ORANGE,
487 _EMOJI_GREEN, _EMOJI_BLUE, _EMOJI_RED, _EMOJI_ORANGE, _EMOJI_GREEN, _EMOJI_BLUE, _EMOJI_RED, _EMOJI_ORANGE, _EMOJI_GREEN, _EMOJI_BLUE,
488 _EMOJI_PURPLE, _EMOJI_BLACK, _EMOJI_BLUE, _EMOJI_GREEN, _EMOJI_BLACK, _EMOJI_BLUE, _EMOJI_ORANGE, _EMOJI_BLACK, _EMOJI_PURPLE, _EMOJI_GREEN,
489 _EMOJI_ORANGE, _EMOJI_BLUE, _EMOJI_BLACK, _EMOJI_GREEN, _EMOJI_RED, _EMOJI_BLUE, _EMOJI_BLUE, _EMOJI_RED, _EMOJI_BLUE, _EMOJI_RED,
490 _EMOJI_BLACK, _EMOJI_PURPLE, _EMOJI_RED, _EMOJI_GREEN, _EMOJI_BLUE, _EMOJI_PURPLE, _EMOJI_BLUE, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK,
491 _EMOJI_GREEN, _EMOJI_PURPLE, _EMOJI_ORANGE, _EMOJI_ORANGE, _EMOJI_RED, _EMOJI_BLUE, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_ORANGE,
492 _EMOJI_BLUE, _EMOJI_PURPLE, _EMOJI_BLACK, _EMOJI_RED, _EMOJI_ORANGE, _EMOJI_BLACK, _EMOJI_RED, _EMOJI_BLACK, _EMOJI_RED, _EMOJI_ORANGE,
493 _EMOJI_RED, _EMOJI_RED, _EMOJI_RED, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_ORANGE, _EMOJI_BLUE, _EMOJI_BLACK, _EMOJI_BLUE, _EMOJI_RED,
494 _EMOJI_BLACK, _EMOJI_RED, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_ORANGE, _EMOJI_ORANGE, _EMOJI_ORANGE, _EMOJI_ORANGE, _EMOJI_BLACK, _EMOJI_BLACK,
495 _EMOJI_ORANGE, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLUE, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_ORANGE,
496 _EMOJI_ORANGE, _EMOJI_BLUE, _EMOJI_GREEN, _EMOJI_BLACK, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI,
497 _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _NOT_EMOJI, _NOT_EMOJI, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _NOT_EMOJI, _NOT_EMOJI,
498 _NOT_EMOJI, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI,
499 _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI,
500 _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_ORANGE, _EMOJI_ORANGE, _EMOJI_BLACK,
501 _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_RED, _EMOJI_RED, _EMOJI_RED, _EMOJI_RED, _EMOJI_RED, _EMOJI_RED, _EMOJI_BLUE, _EMOJI_RED,
502 _EMOJI_RED, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK,
503 _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_RED, _EMOJI_RED, _EMOJI_RED, _EMOJI_RED, _EMOJI_PURPLE, _EMOJI_RED,
504 _EMOJI_BLUE, _EMOJI_GREEN, _EMOJI_BLUE, _EMOJI_RED, _EMOJI_RED, _EMOJI_RED, _EMOJI_PURPLE, _EMOJI_RED, _EMOJI_ORANGE, _EMOJI_ORANGE,
505 _EMOJI_BLACK, _EMOJI_RED, _EMOJI_BLACK, _EMOJI_RED, _EMOJI_BLUE, _EMOJI_BLUE, _EMOJI_RED, _EMOJI_PURPLE, _EMOJI_RED, _EMOJI_RED,
506 _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_RED, _EMOJI_ORANGE, _EMOJI_ORANGE, _EMOJI_BLUE, _EMOJI_BLACK,
507 _EMOJI_RED, _EMOJI_DARK_BLUE, _EMOJI_BLUE, _EMOJI_ORANGE, _EMOJI_BROWN, _EMOJI_BROWN, _EMOJI_BLACK, _EMOJI_RED, _EMOJI_BLACK, _EMOJI_GREEN,
508 _EMOJI_ORANGE, _EMOJI_PURPLE, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_GREEN, _EMOJI_BLACK, _EMOJI_GREEN, _EMOJI_PURPLE, _EMOJI_BLUE, _EMOJI_BLUE,
509 _EMOJI_RED, _EMOJI_DEEP_PURPLE, _EMOJI_PURPLE, _EMOJI_ORANGE, _EMOJI_RED, _EMOJI_PURPLE, _EMOJI_PURPLE, _EMOJI_DARK_BLUE, _EMOJI_ORANGE, _EMOJI_BLUE,
510 _EMOJI_BLUE, _EMOJI_RED, _EMOJI_BLUE, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_RED, _EMOJI_GREEN, _EMOJI_BLACK, _EMOJI_ORANGE,
511 _EMOJI_RED, _EMOJI_BLUE, _EMOJI_RED, _EMOJI_RED, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_GREEN, _EMOJI_BLUE, _EMOJI_BLUE, _EMOJI_GREEN,
512 _EMOJI_RED, _EMOJI_RED, _EMOJI_ORANGE, _EMOJI_RED, _EMOJI_GREEN, _EMOJI_RED, _EMOJI_PURPLE, _EMOJI_BLACK, _EMOJI_RED, _EMOJI_BROWN,
513 _EMOJI_ORANGE, _EMOJI_BROWN, _EMOJI_BROWN, _EMOJI_ORANGE, _EMOJI_DARK_BLUE, _EMOJI_BLUE, _EMOJI_ORANGE, _EMOJI_ORANGE, _EMOJI_BROWN, _EMOJI_ORANGE,
514 _EMOJI_DEEP_PURPLE, _EMOJI_DEEP_PURPLE
517 if (unicode >= _MIN_EMOJI_UNICODE && unicode <= _MAX_EMOJI_UNICODE)
519 if (_emojiTable[unicode - _MIN_EMOJI_UNICODE] != _NOT_EMOJI)
521 fgColor = _emojiTable[unicode - _MIN_EMOJI_UNICODE];
531 _Util::String textFragment;
534 _TextFragment(const _Util::String& string, _IFont* pFont)
535 : textFragment(string)
544 namespace Tizen { namespace Graphics
552 _Font::_Font(const _Font& obj)
554 this->__fontAttrib = obj.__fontAttrib;
555 this->__sharedFont = obj.__sharedFont;
565 _Font::Construct(int style, _Util::FixedPoint26_6 pcSize)
567 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
569 // use default system font
570 _FontRsrcManager::SharedFontResource out;
571 result r = mgr.GetFont(style, pcSize, out);
572 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get system default font", GetErrorMessage(r));
576 __UpdateFontAttribute(style, pcSize);
582 _Font::Construct(const Tizen::Base::String& fontName, int style, _Util::FixedPoint26_6 pcSize, bool isPathEnabled)
584 bool systemFont = false;
585 String appFontPath = L"";
586 result r = E_SUCCESS;
588 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
589 _FontRsrcManager::SharedFontResource out;
591 if (!Tizen::App::_AppInfo::IsOspCompat())
593 _Util::WString fontNameTemp(fontName.GetPointer());
594 _Util::WString appFontPathTemp(mgr.FindAppFontName(fontNameTemp));
595 appFontPath.Append(appFontPathTemp.c_str());
598 // check if user want to use a app font
599 if (!appFontPath.IsEmpty())
601 r = mgr.GetFont(appFontPath, style, pcSize, out);
602 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get app font", GetErrorMessage(r));
606 IList* pList = GetSystemFontListN();
611 for (idx = 0; idx < pList->GetCount(); idx++)
613 String* pName = static_cast <String*>(pList->GetAt(idx));
620 if (*pName == fontName)
627 pList->RemoveAll(true);
633 r = mgr.GetSystemFont(fontName, style, pcSize, out);
634 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get system font", GetErrorMessage(r));
636 else if (isPathEnabled)
638 r = mgr.GetFont(fontName, style, pcSize, out);
639 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get font", GetErrorMessage(r));
645 __UpdateFontAttribute(style, pcSize);
651 _Font::Construct(const Tizen::Base::ByteBuffer& fontData, int style, _Util::FixedPoint26_6 pcSize)
653 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
655 const byte* pBuffer = fontData.GetPointer();
656 int buffSize = fontData.GetLimit();
658 _FontRsrcManager::SharedFontResource out;
659 result r = mgr.GetFont(pBuffer, buffSize, style, pcSize, out);
660 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get system font", GetErrorMessage(r));
664 __UpdateFontAttribute(style, pcSize);
670 _Font::IsConstructed(void) const
672 return (__sharedFont.get() != null);
675 _Util::FixedPoint26_6
676 _Font::GetMaxHeight(void) const
678 return __fontAttrib.maxHeight;
681 _Util::FixedPoint26_6
682 _Font::GetMaxWidth(void) const
684 return __fontAttrib.maxWidth;
687 _Util::FixedPoint26_6
688 _Font::GetAscender(void) const
690 return __fontAttrib.ascender;
693 _Util::FixedPoint26_6
694 _Font::GetDescender(void) const
696 return __fontAttrib.descender;
700 _Font::GetLeftBear(wchar_t character, _Util::FixedPoint22_10& leftBear) const
704 _IFont::Glyph* pFontGlyphData = null;
705 LOAD_GLYPH_DATA_CONST(character, pFontGlyphData, E_SYSTEM);
707 // left bear is Glyph::xOffset, set it
708 leftBear = pFontGlyphData->xOffset;
710 UNLOAD_GLYPH_DATA_CONST(pFontGlyphData);
716 _Font::GetRightBear(wchar_t character, _Util::FixedPoint22_10& rightBear) const
720 _IFont::Glyph* pFontGlyphData = null;
721 LOAD_GLYPH_DATA_CONST(character, pFontGlyphData, E_SYSTEM);
723 // right bear is Glyph::xOffset + GlyphBitmap::width, set it
724 rightBear = pFontGlyphData->xOffset + _Util::FixedPoint22_10(pFontGlyphData->image.width);
726 UNLOAD_GLYPH_DATA_CONST(pFontGlyphData);
732 _Font::IsBold(void) const
734 return ((__fontAttrib.style & FONT_STYLE_BOLD) ? true : false);
738 _Font::IsItalic(void) const
740 return ((__fontAttrib.style & FONT_STYLE_ITALIC) ? true : false);
744 _Font::IsPlain(void) const
746 return ((__fontAttrib.style & FONT_STYLE_PLAIN) ? true : false);
750 _Font::IsStrikeOut(void) const
752 return __fontAttrib.strikeout;
756 _Font::IsUnderlined(void) const
758 return __fontAttrib.underline;
761 _Util::FixedPoint26_6
762 _Font::GetSize(void) const
764 return __fontAttrib.size;
768 _Font::SetStrikeOut(bool strikeout)
770 __fontAttrib.strikeout = strikeout;
774 _Font::SetUnderline(bool underline)
776 __fontAttrib.underline = underline;
780 _Font::SetCharSpace(int pc_space)
782 __fontAttrib.charSpace = pc_space;
786 _Font::GetCharSpace(void) const
788 return __fontAttrib.charSpace;
792 _Font::GetLineThickness(void) const
794 return __fontAttrib.lineThickness;
798 _Font::GetFaceName(void) const
800 _IFont::Property property;
801 GET_FONT_PROPERTY(property, String());
803 return ((property.pFamilyName) ? String(property.pFamilyName) : String());
806 Tizen::Base::Collection::IList*
807 _Font::GetSystemFontListN(void)
809 std::auto_ptr<ArrayList> pList(new (std::nothrow) Tizen::Base::Collection::ArrayList);
810 SysTryReturn(NID_GRP, pList.get(), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Fails to allocate memory");
812 result r = _GetSystemFontList(*pList);
813 SysTryReturn(NID_GRP, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
815 return pList.release();
820 _Font::GetFaceName(const Tizen::Base::String& filePath)
822 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
823 _FontRsrcManager::SharedFontResource out;
826 result r = mgr.GetTempFont(filePath, FONT_STYLE_PLAIN, _SYSTEM_DEFAULT_FONT_SIZE, out);
827 SysTryReturn(NID_GRP, r == E_SUCCESS, faceName, r, "[%s] Failed to get font", GetErrorMessage(r));
831 _IFont* pTempFont = out.get();
833 _IFont::Property property;
834 pTempFont->GetFontProperty(property);
835 faceName = String(property.pFamilyName);
842 _Font::GetNativeFont(void) const
844 return __pNativeFont;
851 _Font* pNativeFont = new (std::nothrow) _Font(*this);
852 SysTryReturn(NID_GRP, pNativeFont, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocated memory");
859 _Font::ApplyAttribute()
861 _IFont::Attrib fontAttrib;
862 bool rtn = __pNativeFont->GetAttrib(fontAttrib);
863 SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to get font attribute");
865 fontAttrib.size = __fontAttrib.size;
866 fontAttrib.style = _IFont::STYLE_NONE;
867 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
868 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
869 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
870 rtn = __pNativeFont->SetAttrib(fontAttrib);
871 SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to set font attribute");
877 _Font::GetTextExtent(int width, const _Util::String& text, bool outline, int& count, Dimension& pcDim) const
879 if (text.pStart == null || text.length <= 0)
886 _TextBidiPropertyWithReorder bidiProperty(text.pStart, text.length);
888 if (bidiProperty.HasBidi())
890 typedef _Util::AccumList<_Util::Pair<int, int> > GapList;
894 result r = this->__GetTextExtentList(bidiProperty, gapList);
903 int determinedCount = -1;
905 for (GapList::Iterator i = gapList.Begin(); i != gapList.End(); ++i)
907 left = (i->first < left) ? i->first : left;
908 right = (i->second > right) ? i->second : right;
910 if (determinedCount < 0 && i->first < width && i->second >= width)
912 if (i != gapList.Begin())
914 if (i - gapList.Begin() - 1 < text.length)
916 determinedCount = bidiProperty.pBidiIndex[i - gapList.Begin() - 1];
920 determinedCount = text.length;
925 determinedCount = bidiProperty.pBidiIndex[0];
930 if (right - left <= width)
932 pcDim.SetSize(right - left, __fontAttrib.size.ToInt());
935 else if (determinedCount > 0 && right - left > 0)
937 int expectedValue = width * text.length / (right - left);
938 int tolerance = _Util::Abs(expectedValue - determinedCount);
939 tolerance = (tolerance == 0) ? 2 : tolerance;
941 int tempCount = expectedValue <= determinedCount ? determinedCount + tolerance : determinedCount + (tolerance * 2);
942 tempCount = tempCount > text.length ? text.length : tempCount;
946 while (right - left > width)
948 _TextBidiPropertyWithReorder determinedBidiProperty(text.pStart, --tempCount);
950 GapList determinedGapList;
952 result r = this->__GetTextExtentList(determinedBidiProperty, determinedGapList);
962 for (GapList::Iterator i = determinedGapList.Begin(); i != determinedGapList.End(); ++i)
964 left = (i->first < left) ? i->first : left;
965 right = (i->second > right) ? i->second : right;
969 pcDim.SetSize(right - left, __fontAttrib.size.ToInt());
982 return this->__GetTextExtent(width, text, outline, count, pcDim);
989 _Font::__GetTextExtent(int width, const _Util::String& text, bool outline, int& count, Dimension& pcDim) const
991 if (text.pStart == null)
994 SysTryReturn(NID_GRP, false, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The given string is invalid.");
997 int preX1 = 0x7FFFFFFF;
998 int preY1 = 0x7FFFFFFF;
999 int preX2 = -0x7FFFFFFF;
1000 int preY2 = -0x7FFFFFFF;
1002 int x1 = 0x7FFFFFFF;
1003 int y1 = 0x7FFFFFFF;
1004 int x2 = -0x7FFFFFFF;
1005 int y2 = -0x7FFFFFFF;
1011 int italicSpace = 0;
1017 wchar_t leftChar = 0;
1019 _IFont::Glyph* pFontGlyphData = 0;
1021 if (text.length == 0)
1024 pcDim.SetSize(0, 0);
1028 _Font* pThis = const_cast <_Font*>(this);
1030 APPLY_ATTRIBUTE(E_SYSTEM);
1033 _IFont::SizeProperty sizeProperty;
1034 GET_FONT_SIZE_PROPERTY(sizeProperty, E_SYSTEM);
1036 if (__fontAttrib.style & FONT_STYLE_ITALIC)
1038 italicSpace = (sizeProperty.ascender.ToInt() * 2) >> 4;
1042 _IFont::Property property;
1043 GET_FONT_PROPERTY(property, false);
1045 if (__fontAttrib.style & FONT_STYLE_BOLD && property.weightClass < _MEDIUM_FONT_BOLD_WEIGHT)
1047 _IFont::Attrib attr;
1048 pThis->GetAttrib(attr);
1049 boldSpace = static_cast<int>(attr.boldWeight.ToFloat() + 0.5f);
1052 const wchar_t* pText = text.pStart;
1053 int length = text.length;
1055 while (*pText && --length >= 0)
1057 // getting proper _Font instance for the specified text
1058 _IFont* pFont = pThis->__GetFont(*pText);
1060 if (pFont != __pNativeFont)
1062 _IFont::Attrib fontAttrib;
1063 bool rtn = pFont->GetAttrib(fontAttrib);
1064 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to get font attribute");
1066 fontAttrib.size = __fontAttrib.size;
1067 fontAttrib.style = _IFont::STYLE_NONE;
1068 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
1069 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
1070 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
1071 rtn = pFont->SetAttrib(fontAttrib);
1072 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to set font attribute");
1077 if (pFont->GetKerning(leftChar, *pText, xVec, yVec))
1083 if (pFont->LoadGlyph(*pText++, &pFontGlyphData))
1085 int glyphBoundX1 = curX;
1086 int glyphBoundY1 = curY - pFontGlyphData->yOffset.ToInt();
1087 int glyphBoundX2 = glyphBoundX1 +
1088 ((pFontGlyphData->image.width <= 0) ? pFontGlyphData->xAdvance.ToInt()
1089 : (pFontGlyphData->xOffset.ToInt() + pFontGlyphData->image.width));
1090 int glyphBoundY2 = glyphBoundY1 + pFontGlyphData->image.height;
1092 #ifdef SYNCHRONIZATION_2_0
1093 // adjusting x2 bounds for synchronizing fuctionality with 2.0
1094 glyphBoundX2 = glyphBoundX1 + pFontGlyphData->xAdvance.ToInt() + italicSpace + boldSpace;
1104 _ExpandBounds(glyphBoundX1, glyphBoundY1, x1, y1, x2, y2);
1105 _ExpandBounds(glyphBoundX2, glyphBoundY1, x1, y1, x2, y2);
1106 _ExpandBounds(glyphBoundX1, glyphBoundY2, x1, y1, x2, y2);
1107 _ExpandBounds(glyphBoundX2, glyphBoundY2, x1, y1, x2, y2);
1109 #ifdef SYNCHRONIZATION_2_0
1110 curX += pFontGlyphData->xAdvance.ToInt() + __fontAttrib.charSpace + italicSpace + boldSpace;
1112 curX += pFontGlyphData->xAdvance.ToInt() + __fontAttrib.charSpace + boldSpace;
1114 curY += pFontGlyphData->yAdvance.ToInt();
1116 pFont->UnloadGlyph(&pFontGlyphData);
1118 // check end condition
1119 // TODO, shkim, BIDI need to be cared
1120 if ((x2 - x1) > width)
1131 leftChar = *(pText - 1);
1135 if (characters == 0)
1137 pcDim.SetSize(0, 0);
1142 SysTryCatch(NID_GRP, preX1 <= preX2 && preY1 <= preY2, pcDim.SetSize(0, 0); count = 0, E_SYSTEM, "[E_SYSTEM] Failed to calculate text extent");
1145 pcDim.width = preX2 - preX1;
1146 #ifdef SYNCHRONIZATION_2_0
1147 pcDim.height = __fontAttrib.size.ToInt();
1149 pcDim.height = preY2 - preY1;
1150 #endif // SYNCHRONIZATION_2_0
1159 _Font::GetTextExtent(int width, const _Util::String& text, bool outline, const Tizen::Base::String& delimiter, int& count, Dimension& dim) const
1161 const wchar_t* pText = text.pStart;
1162 const wchar_t* pTextEnd = pText + text.length;
1164 while (pText < pTextEnd)
1166 if (*pText == 0x0D || *pText == 0x0A)
1175 return this->GetTextExtent(width, _Util::String(text.pStart, pTextEnd - text.pStart), outline, count, dim);
1179 _Font::__GetTextExtentList(const _Util::String& text, _Util::AccumList<_Util::Pair<int, int> >& outList) const
1181 SysAssert(text.pStart != null && text.length > 0);
1185 _Font* pThis = const_cast <_Font*>(this);
1187 APPLY_ATTRIBUTE(E_SYSTEM);
1189 int addingSpace = __fontAttrib.charSpace;
1191 #ifdef SYNCHRONIZATION_2_0
1193 _IFont::SizeProperty sizeProperty;
1195 GET_FONT_SIZE_PROPERTY(sizeProperty, E_SYSTEM);
1197 if (__fontAttrib.style & FONT_STYLE_ITALIC)
1199 addingSpace += (sizeProperty.ascender.ToInt() * 2) >> 4;
1204 _IFont::Property property;
1205 GET_FONT_PROPERTY(property, false);
1207 if (__fontAttrib.style & FONT_STYLE_BOLD && property.weightClass < _MEDIUM_FONT_BOLD_WEIGHT)
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 _IFont::SizeProperty sizeProperty;
1555 rtn = this->GetFontSizeProperty(sizeProperty);
1556 SysTryReturn(NID_GRP, rtn, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to get font sizeProperty.");
1558 // need to revise y value, because _IFont is based on the baseline
1560 if (canvas.__textOrigin == TEXT_ORIGIN_LEFT_TOP)
1562 yDest += sizeProperty.ascender.ToInt();
1565 charHeight = sizeProperty.ascender.ToInt() - sizeProperty.descender.ToInt();
1567 if (this->GetStyle() & FONT_STYLE_ITALIC)
1569 italicSpace = (sizeProperty.ascender.ToInt() * 2) >> 4;
1573 _IFont::Property property;
1574 GET_FONT_PROPERTY(property, false);
1576 if (__fontAttrib.style & FONT_STYLE_BOLD && property.weightClass < _MEDIUM_FONT_BOLD_WEIGHT)
1578 _IFont::Attrib attr;
1579 this->GetAttrib(attr);
1580 boldSpace = static_cast<int>(attr.boldWeight.ToFloat() + 0.5f);
1583 unsigned long canvasFgColor = canvas.__fgColor;
1585 _TextBidiPropertyWithReorder bidiProperty(pText, length);
1587 if (bidiProperty.HasBidi())
1589 const wchar_t* pReorderedText = bidiProperty.GetReorderedText();
1591 const wchar_t* pTextFragmentBegin = pReorderedText;
1592 const wchar_t* pTextFragmentEnd = pTextFragmentBegin + length;
1594 const wchar_t* pTextSegment = pTextFragmentBegin;
1596 _IFont* pBaseFont = this->__GetFont(*pTextSegment);
1598 _Util::AccumList<_TextFragment> textFragmentList;
1600 while (pTextSegment < pTextFragmentEnd)
1602 if (pBaseFont->CheckGlyph(*pTextSegment) == 0)
1604 _IFont* pFallbackFont = this->__GetFont(*pTextSegment);
1606 if (pBaseFont != pFallbackFont)
1608 textFragmentList.Push(_TextFragment(_Util::String(pTextFragmentBegin, pTextSegment - pTextFragmentBegin), pBaseFont));
1610 pTextFragmentBegin = pTextSegment;
1611 pBaseFont = pFallbackFont;
1618 textFragmentList.Push(_TextFragment(_Util::String(pTextFragmentBegin, pTextSegment - pTextFragmentBegin), pBaseFont));
1622 * for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.Begin(); textFragment != textFragmentList.End(); ++textFragment)
1625 * for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.End(); textFragment != textFragmentList.Begin(); )
1631 for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.Begin(); textFragment != textFragmentList.End(); ++textFragment)
1633 if (textFragment->pUsingFont == null || textFragment->textFragment.length <= 0)
1638 if (textFragment->pUsingFont != __pNativeFont)
1640 _IFont::Attrib fontAttrib;
1642 if (textFragment->pUsingFont->GetAttrib(fontAttrib))
1644 fontAttrib.size = __fontAttrib.size;
1645 fontAttrib.style = _IFont::STYLE_NONE;
1646 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
1647 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
1648 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
1650 textFragment->pUsingFont->SetAttrib(fontAttrib);
1654 Tizen::Base::Collection::ArrayListT<_IFont::Glyph *> glyphList;
1656 const wchar_t firstChar = *textFragment->textFragment.pStart;
1658 GUnicodeScript script = _TextBidiUtil::GetUnicodeScript(firstChar);
1660 textFragment->pUsingFont->GetGlyphList(textFragment->textFragment, glyphList, script);
1661 // need to check if (script < 0 || script >= _sampleLanguageCount) ?
1663 int count = glyphList.GetCount();
1665 for (int i = 0; i < count; i++)
1668 static int s_index = 0;
1669 const unsigned long COLOR[6] =
1678 unsigned long canvasFgColor = COLOR[s_index++ % 6];
1681 typedef unsigned long TPixel;
1682 _IFont::Glyph *pGlyph = 0;
1684 TPixel srcR, srcG, srcB, srcA;
1685 TPixel dstR, dstG, dstB, dstA;
1687 srcA = (canvasFgColor >> 24) & 0xFF;
1688 srcA += (srcA >> 7);
1689 srcR = (canvasFgColor >> 16) & 0xFF;
1690 srcG = (canvasFgColor >> 8) & 0xFF;
1691 srcB = (canvasFgColor) & 0xFF;
1693 SystemPixel* pBufferStartAddr = null;
1696 scratchPad.GetBuffer(pBufferStartAddr, bufferPitch);
1698 glyphList.GetAt(i, pGlyph);
1700 for (int h = 0; h < pGlyph->image.height; h++)
1702 int y = yDest - pGlyph->yOffset.ToInt() + h;
1714 TPixel* pDest32 = pBufferStartAddr + y * bufferPitch + xDest + pGlyph->xOffset.ToInt();
1716 for (int w = 0; w < pGlyph->image.width; w++)
1718 int x = xDest + pGlyph->xOffset.ToInt() + w;
1731 unsigned long alpha = (unsigned long) (pGlyph->image.pBitmap[h * pGlyph->image.bytesPerLine + w]);
1735 // equivalent to scratchPad.FillRect(x, y, 1, 1, fgColor, alpha);
1736 alpha = (alpha * srcA) >> 8;
1737 alpha += (alpha >> 7);
1739 dstA = (*pDest32 >> 24) & 0xFF;
1740 dstR = (*pDest32 >> 16) & 0xFF;
1741 dstG = (*pDest32 >> 8) & 0xFF;
1742 dstB = (*pDest32) & 0xFF;
1744 dstA = BLEND_ALPHA_COMPONEMT(alpha, dstA);
1745 dstR = (dstR + (((srcR - dstR) * alpha) >> 8)) & 0xFF;
1746 dstG = (dstG + (((srcG - dstG) * alpha) >> 8)) & 0xFF;
1747 dstB = (dstB + (((srcB - dstB) * alpha) >> 8)) & 0xFF;
1749 *pDest32 = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB;
1756 xDest += pGlyph->xAdvance.ToInt();
1757 yDest += pGlyph->yAdvance.ToInt();
1760 IEnumeratorT<_IFont::Glyph*>* pEnum = glyphList.GetEnumeratorN();
1764 while (pEnum->MoveNext() == E_SUCCESS)
1766 _IFont::Glyph* pGlyph;
1768 pEnum->GetCurrent(pGlyph);
1769 pBaseFont->UnloadGlyph(&pGlyph);
1778 while (*pText && --length >= 0)
1780 // find out proper native font
1781 _IFont* pFont = this->__GetFont(*pText);
1788 if (pFont != __pNativeFont)
1790 _IFont::Attrib fontAttrib;
1791 bool rtn = pFont->GetAttrib(fontAttrib);
1792 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to get font attribute");
1794 fontAttrib.size = __fontAttrib.size;
1795 fontAttrib.style = _IFont::STYLE_NONE;
1796 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
1797 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
1798 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
1800 rtn = pFont->SetAttrib(fontAttrib);
1801 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to set font attribute");
1804 _IFont::Property property;
1805 pFont->GetFontProperty(property);
1807 unsigned long fgColor = (canvas.__applyEmoji && pFont->IsEmoji()) ? GetPredefinedColor(*pText, canvasFgColor) : canvasFgColor;
1811 if (pFont->GetKerning(leftChar, *pText, xVec, yVec))
1817 bool rtn = pFont->LoadGlyph(*pText++, &pFontGlyphData);
1824 typedef unsigned long TPixel;
1826 TPixel srcA = (fgColor >> 24) & 0xFF;
1827 srcA += (srcA >> 7);
1829 TPixel srcR = (fgColor >> 16) & 0xFF;
1830 TPixel srcG = (fgColor >> 8) & 0xFF;
1831 TPixel srcB = (fgColor) & 0xFF;
1833 SystemPixel* pBufferStartAddr = null;
1834 int bufferPitch = 0;
1836 scratchPad.GetBuffer(pBufferStartAddr, bufferPitch);
1838 for (int h = 0; h < pFontGlyphData->image.height; h++)
1840 int y = yDest - pFontGlyphData->yOffset.ToInt() + h;
1852 TPixel* pDest32 = pBufferStartAddr + y * bufferPitch + xDest + pFontGlyphData->xOffset.ToInt();
1854 for (int w = 0; w < pFontGlyphData->image.width; w++)
1856 int x = xDest + pFontGlyphData->xOffset.ToInt() + w;
1869 unsigned long alpha = (unsigned long) (pFontGlyphData->image.pBitmap[h * pFontGlyphData->image.bytesPerLine + w]);
1873 // equivalent to scratchPad.FillRect(x, y, 1, 1, fgColor, alpha);
1874 alpha = (alpha * srcA) >> 8;
1875 alpha += (alpha >> 7);
1877 TPixel dstA = (*pDest32 >> 24) & 0xFF;
1878 TPixel dstR = (*pDest32 >> 16) & 0xFF;
1879 TPixel dstG = (*pDest32 >> 8) & 0xFF;
1880 TPixel dstB = (*pDest32) & 0xFF;
1882 dstA = BLEND_ALPHA_COMPONEMT(alpha, dstA);
1883 dstR = (dstR + (((srcR - dstR) * alpha) >> 8)) & 0xFF;
1884 dstG = (dstG + (((srcG - dstG) * alpha) >> 8)) & 0xFF;
1885 dstB = (dstB + (((srcB - dstB) * alpha) >> 8)) & 0xFF;
1887 *pDest32 = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB;
1894 xDest += pFontGlyphData->xAdvance.ToInt() + __fontAttrib.charSpace + italicSpace + boldSpace;
1895 yDest += pFontGlyphData->yAdvance.ToInt();
1897 leftChar = *(pText - 1);
1899 pFont->UnloadGlyph(&pFontGlyphData);
1904 if (this->IsUnderlined() || this->IsStrikeOut())
1907 int thick = this->GetLineThickness();
1909 if (canvas.__textOrigin == TEXT_ORIGIN_LEFT_TOP)
1911 y = point.y + charHeight - 1;
1915 y = point.y - sizeProperty.descender.ToInt() - 1;
1918 xDest -= this->GetCharSpace();
1920 if (this->IsUnderlined())
1922 canvas.FillRectangle(canvasFgColor, Rectangle(startX, y - thick, xDest - startX, thick));
1925 if (this->IsStrikeOut())
1927 y -= charHeight / 2;
1928 canvas.FillRectangle(canvasFgColor, Rectangle(startX, y - thick, xDest - startX, thick));
1932 scratchPad.RegisterFillRect(null);
1938 #undef BLEND_ALPHA_COMPONEMT
1941 _Font::__DrawText(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length, const Color& outlineColor)
1943 unsigned long textColor = canvas.__fgColor;
1944 bool applyEmoji = canvas.__applyEmoji;
1946 //sunmi557.shin: draw border of font
1947 canvas.__fgColor = outlineColor.GetRGB32();
1948 canvas.__applyEmoji = false;
1950 this->__DrawText(canvas, Point(point.x - 1, point.y), text, startIndex, length);
1951 this->__DrawText(canvas, Point(point.x + 1, point.y), text, startIndex, length);
1952 this->__DrawText(canvas, Point(point.x, point.y - 1), text, startIndex, length);
1953 this->__DrawText(canvas, Point(point.x, point.y + 1), text, startIndex, length);
1955 //sunmi557.shin: draw original shape of font
1956 canvas.__applyEmoji = applyEmoji;
1957 canvas.__fgColor = textColor;
1959 this->__DrawText(canvas, point, text, startIndex, length);
1965 _Font::SetAttrib(const _IFont::Attrib& fontAttrib)
1967 return __pNativeFont->SetAttrib(fontAttrib);
1971 _Font::GetAttrib(_IFont::Attrib& fontAttrib) const
1973 return __pNativeFont->GetAttrib(fontAttrib);
1977 _Font::GetKerning(unsigned long character1, unsigned long character2, long& xVector, long& yVector) const
1979 return __pNativeFont->GetKerning(character1, character2, xVector, yVector);
1983 _Font::GetFontSizeProperty(_IFont::SizeProperty& sizeProperty) const
1985 return __pNativeFont->GetFontSizeProperty(sizeProperty);
1989 _Font::LoadGlyph(unsigned long character, _IFont::Glyph** ppFontGlyphData)
1991 // note! we assume that the font attribute has been already applied on _IFont
1994 // if not, loading glyph (character/size/style) and caching it
1995 rtn = __pNativeFont->LoadGlyph(character, ppFontGlyphData);
1996 SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to load glyph data");
1998 // return cached glyph
2003 _Font::UnloadGlyph(_IFont::Glyph** ppFontGlyphData)
2005 return __pNativeFont->UnloadGlyph(ppFontGlyphData);
2009 _Font::CheckGlyph(unsigned long character)
2011 return __pNativeFont->CheckGlyph(character);
2015 _Font::__UpdateFontAttribute(int style, _Util::FixedPoint26_6 pcSize)
2017 __fontAttrib.style = style;
2018 __fontAttrib.size = pcSize;
2019 __fontAttrib.lineThickness = pcSize.ToInt() > 0 ? (pcSize.ToInt() / 24) + 1 : 1;
2021 _IFont::SizeProperty sizeProperty;
2022 bool getProperty = false;
2024 if (this->ApplyAttribute())
2026 getProperty = __pNativeFont->GetFontSizeProperty(sizeProperty);
2031 __fontAttrib.maxWidth = sizeProperty.maxWidth;
2032 __fontAttrib.maxHeight = sizeProperty.maxHeight;
2033 __fontAttrib.ascender = sizeProperty.ascender;
2034 __fontAttrib.descender = sizeProperty.descender;
2038 // if failed to get property above, each property should be remained as default: -1
2039 SysLog(NID_GRP, "[] Failed to get font attribute from native font");
2041 __fontAttrib.maxWidth.Reset(0);
2042 __fontAttrib.maxHeight.Reset(0);
2043 __fontAttrib.ascender.Reset(0);
2044 __fontAttrib.descender.Reset(0);
2049 _Font::__DrawTextLastFallback(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length)
2055 _Font::__DrawTextDefault(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length)
2057 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
2058 result r = mgr.GetDefaultSystemFont().__DrawText(canvas, point, text, startIndex, length);
2059 SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Failed to draw default system font", GetErrorMessage(r));
2064 _Font::__DrawTextLastFallback(canvas, point, text, startIndex, length);
2069 _Font::__DrawTextDefault(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length, const Color& outlineColor)
2071 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
2072 result r = mgr.GetDefaultSystemFont().__DrawText(canvas, point, text, startIndex, length, outlineColor);
2073 SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Failed to draw default system font", GetErrorMessage(r));
2078 _Font::__DrawTextLastFallback(canvas, point, text, startIndex, length);
2084 _Font::DrawText(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length)
2086 if (canvas.__pPriorityFont)
2088 return canvas.__pPriorityFont->__DrawText(canvas, point, text, startIndex, length);
2090 else if (canvas.__pFont)
2092 return canvas.__pFont->__DrawText(canvas, point, text, startIndex, length);
2096 return _Font::__DrawTextDefault(canvas, point, text, startIndex, length);
2101 _Font::DrawText(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length, const Color& outlineColor)
2103 if (canvas.__pPriorityFont)
2105 return canvas.__pPriorityFont->__DrawText(canvas, point, text, startIndex, length, outlineColor);
2107 else if (canvas.__pFont)
2109 return canvas.__pFont->__DrawText(canvas, point, text, startIndex, length, outlineColor);
2113 return _Font::__DrawTextDefault(canvas, point, text, startIndex, length, outlineColor);
2120 _Font::GetInstance(_FontImpl& font)
2122 return (&font != null) ? font._pNativeFont : null;
2126 _Font::GetInstance(const _FontImpl& font)
2128 return (&font != null) ? font._pNativeFont : null;
2132 _Font::__GetFont(wchar_t character)
2134 //------------------------------------------------------
2136 // 1. check if this font has a requested glyph
2138 //------------------------------------------------------
2139 unsigned long idx = __pNativeFont->CheckGlyph(character);
2143 return __pNativeFont;
2146 //------------------------------------------------------
2148 // 1-2. check if this glyph is in the fallback list.
2150 //------------------------------------------------------
2151 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
2152 _IFont::FontMapT* pFallbackFontMap = __pNativeFont->GetFallbackMap();
2154 #ifdef USE_HASHMAP_FOR_FONT
2155 std::auto_ptr<IMapEnumeratorT<_Util::WString, _FontRsrcManager::SharedFontResource> > enumerator(pFallbackFontMap->GetMapEnumeratorN());
2157 while (enumerator->MoveNext() == E_SUCCESS)
2159 _FontRsrcManager::SharedFontResource pTempFont;
2161 if (enumerator->GetValue(pTempFont) == E_SUCCESS)
2163 _Util::WString key(L"");
2164 result r = enumerator->GetKey(key);
2168 if (mgr.SearchFont(key))
2170 if (pTempFont.get()->CheckGlyph(character) > 0)
2172 return pTempFont.get();
2177 pFallbackFontMap->Remove(key);
2183 for (_FontRsrcManager::FontMapT::const_iterator fontIterator = pFallbackFontMap->begin(); fontIterator != pFallbackFontMap->end(); ++fontIterator)
2185 if (fontIterator->second != null)
2187 if (fontIterator->second->CheckGlyph(character) > 0)
2189 return fontIterator->second.get();
2195 //------------------------------------------------------
2197 // 2. Get fallback font list via fontconfig
2199 //------------------------------------------------------
2200 Tizen::Base::Collection::ArrayListT<String> fileList;
2201 bool rtn = __GetFallbackFontFileList(character, fileList);
2205 // if failed find out fallback font,
2206 // just use this instance for drawing something for unknown glyph
2207 return __pNativeFont;
2210 //------------------------------------------------------
2212 // 3. try to find a font having a requested glyph
2214 //------------------------------------------------------
2216 _IFont* pFallbackFont = null;
2218 _FontRsrcManager::SharedFontResource out;
2220 int count = fileList.GetCount();
2221 result r = E_FAILURE;
2223 for (int i = 0; i < count; i++)
2225 fileList.GetAt(i, fontName);
2227 if (fontName.IsEmpty())
2232 r = mgr.GetTempFont(fontName, __fontAttrib.style, __fontAttrib.size, out);
2236 unsigned long idx = out.get()->CheckGlyph(character);
2240 _Util::WString fontNameTemp(fontName.GetPointer());
2243 #ifdef USE_HASHMAP_FOR_FONT
2244 r = pFallbackFontMap->Add(fontNameTemp, out);
2246 if (r == E_OBJ_ALREADY_EXIST)
2248 pFallbackFont = out.get();
2252 SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
2254 pFallbackFontMap->push_back(std::make_pair(fontNameTemp, out));
2256 r = mgr.AddFont(fontNameTemp, out);
2257 SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
2259 pFallbackFont = out.get();
2265 return (pFallbackFont != null) ? pFallbackFont : __pNativeFont;
2268 // if failed find out fallback font,
2269 // just use this instance for drawing something for unknown glyph
2270 return __pNativeFont;
2274 _Font::__GetFallbackFontFileList(wchar_t character, Tizen::Base::Collection::IListT<String>& out)
2276 GUnicodeScript script = g_unichar_get_script(character);
2277 if (script < 0 || script >= _sampleLanguageCount)
2282 _IFont::Property property;
2283 const char* pFamilyName = null;
2284 GET_FONT_PROPERTY(property, false);
2286 pFamilyName = property.pFamilyName;
2288 FcPattern* pPattern = null;
2289 FcFontSet* pSet = null;
2290 FcChar8* pName = null;
2291 FcResult res = FcResultNoMatch;
2292 const char* fcStyle = (__fontAttrib.style & FONT_STYLE_BOLD) ? "Bold" : "Regular";
2294 // getting fallback font list
2295 pPattern = FcPatternBuild(NULL, FC_STYLE, FcTypeString, (FcChar8*)fcStyle, NULL);
2296 SysTryCatch(NID_GRP, pPattern, , E_SYSTEM, "[E_SYSTEM] Failed to FcPatternBuild()");
2298 FcPatternAddString(pPattern, FC_FAMILY, (FcChar8*) pFamilyName);
2300 if (strncmp(SAMPLE_LANGUAGE_EMPTY, _SampleLanguages[script], strlen(SAMPLE_LANGUAGE_EMPTY) + 1) != 0)
2302 FcPatternAddString(pPattern, FC_LANG, (FcChar8*)_SampleLanguages[script]);
2305 FcConfigSubstitute(NULL, pPattern, FcMatchPattern);
2306 FcDefaultSubstitute(pPattern);
2309 pSet = FcFontSort(NULL, pPattern, FcTrue, NULL, &res);
2310 SysTryCatch(NID_GRP, pSet, , E_SYSTEM, "[E_SYSTEM] Failed to FcFontSort()");
2314 for (int i = 0; i < pSet->nfont; i++)
2316 if (FcPatternGetString(pSet->fonts[i], FC_FILE, 0, &pName) == FcResultMatch)
2318 out.Add(String((char*)pName));
2323 FcFontSetDestroy(pSet);
2324 FcPatternDestroy(pPattern);
2326 return (out.GetCount() > 0) ? true : false;
2330 FcFontSetDestroy(pSet);
2333 if (pPattern != null)
2335 FcPatternDestroy(pPattern);
2342 _Font::UpdateDefaultFont(const String& key)
2346 SysLog(NID_GRP, "Request to change the default font");
2348 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
2350 return mgr.ReloadDefaultSystemFont();
2356 }} // Tizen::Graphics