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 { namespace _Util
548 inline Tizen::Graphics::_TextBidiProperty::BidiHint Convert<Tizen::Graphics::TextBidiHint, Tizen::Graphics::_TextBidiProperty::BidiHint>(const Tizen::Graphics::TextBidiHint& bidiHint)
552 case TEXT_BIDI_HINT_LTR:
553 return _TextBidiProperty::BIDI_HINT_LTR;
554 case TEXT_BIDI_HINT_RTL:
555 return _TextBidiProperty::BIDI_HINT_RTL;
557 return _TextBidiProperty::BIDI_HINT_NONE;
561 }}} // Tizen::Graphics::_Util
564 namespace Tizen { namespace Graphics
572 _Font::_Font(const _Font& obj)
574 this->__fontAttrib = obj.__fontAttrib;
575 this->__sharedFont = obj.__sharedFont;
585 _Font::Construct(int style, _Util::FixedPoint26_6 pcSize)
587 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
589 // use default system font
590 _FontRsrcManager::SharedFontResource out;
591 result r = mgr.GetFont(style, pcSize, out);
592 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get system default font", GetErrorMessage(r));
596 __UpdateFontAttribute(style, pcSize);
602 _Font::Construct(const Tizen::Base::String& fontName, int style, _Util::FixedPoint26_6 pcSize, bool isPathEnabled)
604 bool systemFont = false;
605 String appFontPath = L"";
606 result r = E_SUCCESS;
608 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
609 _FontRsrcManager::SharedFontResource out;
611 if (!Tizen::App::_AppInfo::IsOspCompat())
613 _Util::WString fontNameTemp(fontName.GetPointer());
614 _Util::WString appFontPathTemp(mgr.FindAppFontName(fontNameTemp));
615 appFontPath.Append(appFontPathTemp.c_str());
618 // check if user want to use a app font
619 if (!appFontPath.IsEmpty())
621 r = mgr.GetFont(appFontPath, style, pcSize, out);
622 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get app font", GetErrorMessage(r));
626 IList* pList = GetSystemFontListN();
631 for (idx = 0; idx < pList->GetCount(); idx++)
633 String* pName = static_cast <String*>(pList->GetAt(idx));
640 if (*pName == fontName)
647 pList->RemoveAll(true);
653 r = mgr.GetSystemFont(fontName, style, pcSize, out);
654 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get system font", GetErrorMessage(r));
656 else if (isPathEnabled)
658 r = mgr.GetFont(fontName, style, pcSize, out);
659 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get font", GetErrorMessage(r));
665 __UpdateFontAttribute(style, pcSize);
671 _Font::Construct(const Tizen::Base::ByteBuffer& fontData, int style, _Util::FixedPoint26_6 pcSize)
673 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
675 const byte* pBuffer = fontData.GetPointer();
676 int buffSize = fontData.GetLimit();
678 _FontRsrcManager::SharedFontResource out;
679 result r = mgr.GetFont(pBuffer, buffSize, style, pcSize, out);
680 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get system font", GetErrorMessage(r));
684 __UpdateFontAttribute(style, pcSize);
690 _Font::IsConstructed(void) const
692 return (__sharedFont.get() != null);
695 _Util::FixedPoint26_6
696 _Font::GetMaxHeight(void) const
698 return __fontAttrib.maxHeight;
701 _Util::FixedPoint26_6
702 _Font::GetMaxWidth(void) const
704 return __fontAttrib.maxWidth;
707 _Util::FixedPoint26_6
708 _Font::GetAscender(void) const
710 return __fontAttrib.ascender;
713 _Util::FixedPoint26_6
714 _Font::GetDescender(void) const
716 return __fontAttrib.descender;
720 _Font::GetLeftBear(wchar_t character, _Util::FixedPoint22_10& leftBear) const
724 _IFont::Glyph* pFontGlyphData = null;
725 LOAD_GLYPH_DATA_CONST(character, pFontGlyphData, E_SYSTEM);
727 // left bear is Glyph::xOffset, set it
728 leftBear = pFontGlyphData->xOffset;
730 UNLOAD_GLYPH_DATA_CONST(pFontGlyphData);
736 _Font::GetRightBear(wchar_t character, _Util::FixedPoint22_10& rightBear) const
740 _IFont::Glyph* pFontGlyphData = null;
741 LOAD_GLYPH_DATA_CONST(character, pFontGlyphData, E_SYSTEM);
743 // right bear is Glyph::xOffset + GlyphBitmap::width, set it
744 rightBear = pFontGlyphData->xOffset + _Util::FixedPoint22_10(pFontGlyphData->image.width);
746 UNLOAD_GLYPH_DATA_CONST(pFontGlyphData);
752 _Font::IsBold(void) const
754 return ((__fontAttrib.style & FONT_STYLE_BOLD) ? true : false);
758 _Font::IsItalic(void) const
760 return ((__fontAttrib.style & FONT_STYLE_ITALIC) ? true : false);
764 _Font::IsPlain(void) const
766 return ((__fontAttrib.style & FONT_STYLE_PLAIN) ? true : false);
770 _Font::IsStrikeOut(void) const
772 return __fontAttrib.strikeout;
776 _Font::IsUnderlined(void) const
778 return __fontAttrib.underline;
781 _Util::FixedPoint26_6
782 _Font::GetSize(void) const
784 return __fontAttrib.size;
788 _Font::SetStrikeOut(bool strikeout)
790 __fontAttrib.strikeout = strikeout;
794 _Font::SetUnderline(bool underline)
796 __fontAttrib.underline = underline;
800 _Font::SetCharSpace(int pc_space)
802 __fontAttrib.charSpace = pc_space;
806 _Font::GetCharSpace(void) const
808 return __fontAttrib.charSpace;
812 _Font::GetLineThickness(void) const
814 return __fontAttrib.lineThickness;
818 _Font::GetFaceName(void) const
820 _IFont::Property property;
821 GET_FONT_PROPERTY(property, String());
823 return ((property.pFamilyName) ? String(property.pFamilyName) : String());
826 Tizen::Base::Collection::IList*
827 _Font::GetSystemFontListN(void)
829 std::auto_ptr<ArrayList> pList(new (std::nothrow) Tizen::Base::Collection::ArrayList);
830 SysTryReturn(NID_GRP, pList.get(), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Fails to allocate memory");
832 result r = _GetSystemFontList(*pList);
833 SysTryReturn(NID_GRP, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
835 return pList.release();
840 _Font::GetFaceName(const Tizen::Base::String& filePath)
842 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
843 _FontRsrcManager::SharedFontResource out;
846 result r = mgr.GetTempFont(filePath, FONT_STYLE_PLAIN, _SYSTEM_DEFAULT_FONT_SIZE, out);
847 SysTryReturn(NID_GRP, r == E_SUCCESS, faceName, r, "[%s] Failed to get font", GetErrorMessage(r));
851 _IFont* pTempFont = out.get();
853 _IFont::Property property;
854 pTempFont->GetFontProperty(property);
855 faceName = String(property.pFamilyName);
862 _Font::GetNativeFont(void) const
864 return __pNativeFont;
871 _Font* pNativeFont = new (std::nothrow) _Font(*this);
872 SysTryReturn(NID_GRP, pNativeFont, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocated memory");
879 _Font::ApplyAttribute()
881 _IFont::Attrib fontAttrib;
882 bool rtn = __pNativeFont->GetAttrib(fontAttrib);
883 SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to get font attribute");
885 fontAttrib.size = __fontAttrib.size;
886 fontAttrib.style = _IFont::STYLE_NONE;
887 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
888 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
889 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
890 rtn = __pNativeFont->SetAttrib(fontAttrib);
891 SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to set font attribute");
897 _Font::GetTextExtent(int width, const _Util::String& text, bool outline, int& count, Dimension& pcDim) const
899 if (text.pStart == null || text.length <= 0)
906 result r = this->__GetTextExtentEx(width, text, outline, count, pcDim);
913 _TextBidiPropertyWithReorder bidiProperty(text.pStart, text.length, _Util::Convert<TextBidiHint, _TextBidiProperty::BidiHint>(_GetTextBidiHint()));
915 if (bidiProperty.HasComplexText())
917 typedef _Util::AccumList<_Util::Pair<int, int> > GapList;
921 result r = this->__GetTextExtentList(bidiProperty, gapList);
930 int determinedCount = -1;
932 for (GapList::Iterator i = gapList.Begin(); i != gapList.End(); ++i)
934 left = (i->first < left) ? i->first : left;
935 right = (i->second > right) ? i->second : right;
937 if (determinedCount < 0 && i->first < width && i->second >= width)
939 if (i != gapList.Begin())
941 if (i - gapList.Begin() - 1 < text.length)
943 determinedCount = bidiProperty.pBidiIndex[i - gapList.Begin() - 1];
947 determinedCount = text.length;
952 determinedCount = bidiProperty.pBidiIndex[0];
957 if (right - left <= width)
959 pcDim.SetSize(right - left, __fontAttrib.size.ToInt());
962 else if (determinedCount > 0 && right - left > 0)
964 int expectedValue = width * text.length / (right - left);
965 int tolerance = _Util::Abs(expectedValue - determinedCount);
966 tolerance = (tolerance == 0) ? 2 : tolerance;
968 int tempCount = expectedValue <= determinedCount ? determinedCount + tolerance : determinedCount + (tolerance * 2);
969 tempCount = tempCount > text.length ? text.length : tempCount;
973 while (right - left > width)
975 _TextBidiPropertyWithReorder determinedBidiProperty(text.pStart, --tempCount, _Util::Convert<TextBidiHint, _TextBidiProperty::BidiHint>(_GetTextBidiHint()));
977 GapList determinedGapList;
979 result r = this->__GetTextExtentList(determinedBidiProperty, determinedGapList);
989 for (GapList::Iterator i = determinedGapList.Begin(); i != determinedGapList.End(); ++i)
991 left = (i->first < left) ? i->first : left;
992 right = (i->second > right) ? i->second : right;
996 pcDim.SetSize(right - left, __fontAttrib.size.ToInt());
1001 pcDim.SetSize(0, 0);
1009 return this->__GetTextExtent(width, text, outline, count, pcDim);
1016 _Font::__GetTextExtentEx(int width, const _Util::String& text, bool outline, int& count, Dimension& pcDim) const
1018 int preX1 = 0x7FFFFFFF;
1019 int preY1 = 0x7FFFFFFF;
1020 int preX2 = -0x7FFFFFFF;
1021 int preY2 = -0x7FFFFFFF;
1023 int x1 = 0x7FFFFFFF;
1024 int y1 = 0x7FFFFFFF;
1025 int x2 = -0x7FFFFFFF;
1026 int y2 = -0x7FFFFFFF;
1032 int italicSpace = 0;
1038 wchar_t leftChar = 0;
1040 _IFont::Glyph* pFontGlyphData = 0;
1042 _Font* pThis = const_cast <_Font*>(this);
1044 APPLY_ATTRIBUTE(E_SYSTEM);
1047 _IFont::SizeProperty sizeProperty;
1048 GET_FONT_SIZE_PROPERTY(sizeProperty, E_SYSTEM);
1050 if (__fontAttrib.style & FONT_STYLE_ITALIC)
1052 italicSpace = (sizeProperty.ascender.ToInt() * 2) >> 4;
1056 _IFont::Property property;
1057 GET_FONT_PROPERTY(property, false);
1059 if (__fontAttrib.style & FONT_STYLE_BOLD && property.weightClass < _MEDIUM_FONT_BOLD_WEIGHT)
1061 _IFont::Attrib attr;
1062 pThis->GetAttrib(attr);
1063 boldSpace = static_cast<int>(attr.boldWeight.ToFloat() + 0.5f);
1066 const wchar_t* pText = text.pStart;
1067 int length = text.length;
1069 while (*pText && --length >= 0)
1072 FriBidiCharType type = fribidi_get_bidi_type((FriBidiChar) *pText);
1074 GUnicodeScript script = g_unichar_get_script(*pText);
1076 if (FRIBIDI_IS_LETTER(type) && FRIBIDI_IS_RTL(type))
1080 else if (script == G_UNICODE_SCRIPT_DEVANAGARI || script == G_UNICODE_SCRIPT_BENGALI)
1086 // getting proper _Font instance for the specified text
1087 _IFont* pFont = pThis->__GetFont(*pText);
1089 if (pFont != __pNativeFont)
1091 _IFont::Attrib fontAttrib;
1092 bool rtn = pFont->GetAttrib(fontAttrib);
1093 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to get font attribute");
1095 fontAttrib.size = __fontAttrib.size;
1096 fontAttrib.style = _IFont::STYLE_NONE;
1097 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
1098 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
1099 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
1100 rtn = pFont->SetAttrib(fontAttrib);
1101 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to set font attribute");
1106 if (pFont->GetKerning(leftChar, *pText, xVec, yVec))
1112 if (pFont->LoadGlyph(*pText++, &pFontGlyphData))
1114 int glyphBoundX1 = curX;
1115 int glyphBoundY1 = curY - pFontGlyphData->yOffset.ToInt();
1116 int glyphBoundX2 = glyphBoundX1 +
1117 ((pFontGlyphData->image.width <= 0) ? pFontGlyphData->xAdvance.ToInt()
1118 : (pFontGlyphData->xOffset.ToInt() + pFontGlyphData->image.width));
1119 int glyphBoundY2 = glyphBoundY1 + pFontGlyphData->image.height;
1121 #ifdef SYNCHRONIZATION_2_0
1122 // adjusting x2 bounds for synchronizing fuctionality with 2.0
1123 glyphBoundX2 = glyphBoundX1 + pFontGlyphData->xAdvance.ToInt() + italicSpace + boldSpace;
1133 _ExpandBounds(glyphBoundX1, glyphBoundY1, x1, y1, x2, y2);
1134 _ExpandBounds(glyphBoundX2, glyphBoundY1, x1, y1, x2, y2);
1135 _ExpandBounds(glyphBoundX1, glyphBoundY2, x1, y1, x2, y2);
1136 _ExpandBounds(glyphBoundX2, glyphBoundY2, x1, y1, x2, y2);
1138 #ifdef SYNCHRONIZATION_2_0
1139 curX += pFontGlyphData->xAdvance.ToInt() + __fontAttrib.charSpace + italicSpace + boldSpace;
1141 curX += pFontGlyphData->xAdvance.ToInt() + __fontAttrib.charSpace + boldSpace;
1143 curY += pFontGlyphData->yAdvance.ToInt();
1145 pFont->UnloadGlyph(&pFontGlyphData);
1147 // check end condition
1148 // TODO, shkim, BIDI need to be cared
1149 if ((x2 - x1) > width)
1160 leftChar = *(pText - 1);
1164 if (characters == 0)
1166 pcDim.SetSize(0, 0);
1171 SysTryCatch(NID_GRP, preX1 <= preX2 && preY1 <= preY2, pcDim.SetSize(0, 0); count = 0, E_SYSTEM, "[E_SYSTEM] Failed to calculate text extent");
1174 pcDim.width = preX2 - preX1;
1175 #ifdef SYNCHRONIZATION_2_0
1176 pcDim.height = __fontAttrib.size.ToInt();
1178 pcDim.height = preY2 - preY1;
1179 #endif // SYNCHRONIZATION_2_0
1188 _Font::__GetTextExtent(int width, const _Util::String& text, bool outline, int& count, Dimension& pcDim) const
1190 if (text.pStart == null)
1192 pcDim.SetSize(0, 0);
1193 SysTryReturn(NID_GRP, false, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The given string is invalid.");
1196 int preX1 = 0x7FFFFFFF;
1197 int preY1 = 0x7FFFFFFF;
1198 int preX2 = -0x7FFFFFFF;
1199 int preY2 = -0x7FFFFFFF;
1201 int x1 = 0x7FFFFFFF;
1202 int y1 = 0x7FFFFFFF;
1203 int x2 = -0x7FFFFFFF;
1204 int y2 = -0x7FFFFFFF;
1210 int italicSpace = 0;
1216 wchar_t leftChar = 0;
1218 _IFont::Glyph* pFontGlyphData = 0;
1220 if (text.length == 0)
1223 pcDim.SetSize(0, 0);
1227 _Font* pThis = const_cast <_Font*>(this);
1229 APPLY_ATTRIBUTE(E_SYSTEM);
1232 _IFont::SizeProperty sizeProperty;
1233 GET_FONT_SIZE_PROPERTY(sizeProperty, E_SYSTEM);
1235 if (__fontAttrib.style & FONT_STYLE_ITALIC)
1237 italicSpace = (sizeProperty.ascender.ToInt() * 2) >> 4;
1241 _IFont::Property property;
1242 GET_FONT_PROPERTY(property, false);
1244 if (__fontAttrib.style & FONT_STYLE_BOLD && property.weightClass < _MEDIUM_FONT_BOLD_WEIGHT)
1246 _IFont::Attrib attr;
1247 pThis->GetAttrib(attr);
1248 boldSpace = static_cast<int>(attr.boldWeight.ToFloat() + 0.5f);
1251 const wchar_t* pText = text.pStart;
1252 int length = text.length;
1254 while (*pText && --length >= 0)
1256 // getting proper _Font instance for the specified text
1257 _IFont* pFont = pThis->__GetFont(*pText);
1259 if (pFont != __pNativeFont)
1261 _IFont::Attrib fontAttrib;
1262 bool rtn = pFont->GetAttrib(fontAttrib);
1263 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to get font attribute");
1265 fontAttrib.size = __fontAttrib.size;
1266 fontAttrib.style = _IFont::STYLE_NONE;
1267 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
1268 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
1269 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
1270 rtn = pFont->SetAttrib(fontAttrib);
1271 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to set font attribute");
1276 if (pFont->GetKerning(leftChar, *pText, xVec, yVec))
1282 if (pFont->LoadGlyph(*pText++, &pFontGlyphData))
1284 int glyphBoundX1 = curX;
1285 int glyphBoundY1 = curY - pFontGlyphData->yOffset.ToInt();
1286 int glyphBoundX2 = glyphBoundX1 +
1287 ((pFontGlyphData->image.width <= 0) ? pFontGlyphData->xAdvance.ToInt()
1288 : (pFontGlyphData->xOffset.ToInt() + pFontGlyphData->image.width));
1289 int glyphBoundY2 = glyphBoundY1 + pFontGlyphData->image.height;
1291 #ifdef SYNCHRONIZATION_2_0
1292 // adjusting x2 bounds for synchronizing fuctionality with 2.0
1293 glyphBoundX2 = glyphBoundX1 + pFontGlyphData->xAdvance.ToInt() + italicSpace + boldSpace;
1303 _ExpandBounds(glyphBoundX1, glyphBoundY1, x1, y1, x2, y2);
1304 _ExpandBounds(glyphBoundX2, glyphBoundY1, x1, y1, x2, y2);
1305 _ExpandBounds(glyphBoundX1, glyphBoundY2, x1, y1, x2, y2);
1306 _ExpandBounds(glyphBoundX2, glyphBoundY2, x1, y1, x2, y2);
1308 #ifdef SYNCHRONIZATION_2_0
1309 curX += pFontGlyphData->xAdvance.ToInt() + __fontAttrib.charSpace + italicSpace + boldSpace;
1311 curX += pFontGlyphData->xAdvance.ToInt() + __fontAttrib.charSpace + boldSpace;
1313 curY += pFontGlyphData->yAdvance.ToInt();
1315 pFont->UnloadGlyph(&pFontGlyphData);
1317 // check end condition
1318 // TODO, shkim, BIDI need to be cared
1319 if ((x2 - x1) > width)
1330 leftChar = *(pText - 1);
1334 if (characters == 0)
1336 pcDim.SetSize(0, 0);
1341 SysTryCatch(NID_GRP, preX1 <= preX2 && preY1 <= preY2, pcDim.SetSize(0, 0); count = 0, E_SYSTEM, "[E_SYSTEM] Failed to calculate text extent");
1344 pcDim.width = preX2 - preX1;
1345 #ifdef SYNCHRONIZATION_2_0
1346 pcDim.height = __fontAttrib.size.ToInt();
1348 pcDim.height = preY2 - preY1;
1349 #endif // SYNCHRONIZATION_2_0
1358 _Font::GetTextExtent(int width, const _Util::String& text, bool outline, const Tizen::Base::String& delimiter, int& count, Dimension& dim) const
1360 const wchar_t* pText = text.pStart;
1361 const wchar_t* pTextEnd = pText + text.length;
1363 while (pText < pTextEnd)
1365 if (*pText == 0x0D || *pText == 0x0A)
1374 return this->GetTextExtent(width, _Util::String(text.pStart, pTextEnd - text.pStart), outline, count, dim);
1378 _Font::__GetTextExtentList(const _Util::String& text, _Util::AccumList<_Util::Pair<int, int> >& outList) const
1380 SysAssert(text.pStart != null && text.length > 0);
1384 _Font* pThis = const_cast <_Font*>(this);
1386 APPLY_ATTRIBUTE(E_SYSTEM);
1388 int addingSpace = __fontAttrib.charSpace;
1390 #ifdef SYNCHRONIZATION_2_0
1392 _IFont::SizeProperty sizeProperty;
1394 GET_FONT_SIZE_PROPERTY(sizeProperty, E_SYSTEM);
1396 if (__fontAttrib.style & FONT_STYLE_ITALIC)
1398 addingSpace += (sizeProperty.ascender.ToInt() * 2) >> 4;
1403 _IFont::Property property;
1404 GET_FONT_PROPERTY(property, false);
1406 if (__fontAttrib.style & FONT_STYLE_BOLD && property.weightClass < _MEDIUM_FONT_BOLD_WEIGHT)
1408 _IFont::Attrib attr;
1410 if (pThis->GetAttrib(attr))
1412 addingSpace += static_cast<int>(attr.boldWeight.ToFloat() + 0.5f);
1418 wchar_t prevChar = 0;
1420 const wchar_t* pText = text.pStart;
1421 int length = text.length;
1425 while (*(++pText) && --length >= 0)
1427 _IFont* pFont = pThis->__GetFont(*pText);
1431 if (pFont != __pNativeFont)
1433 _IFont::Attrib fontAttrib;
1435 if (pFont->GetAttrib(fontAttrib))
1437 fontAttrib.size = __fontAttrib.size;
1438 fontAttrib.style = _IFont::STYLE_NONE;
1439 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
1440 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
1441 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
1442 pFont->SetAttrib(fontAttrib);
1446 _IFont::Glyph* pFontGlyphData = 0;
1448 if (pFont->LoadGlyph(*pText, &pFontGlyphData))
1450 // When LoadGlyph fails continuously in the original code, there is a problem to check the kerning on the results of the previous prevChar
1456 if (pFont->GetKerning(prevChar, *pText, xVec, yVec))
1464 curX += pFontGlyphData->xAdvance.ToInt() + addingSpace;
1465 curY += pFontGlyphData->yAdvance.ToInt();
1467 pFont->UnloadGlyph(&pFontGlyphData);
1470 outList.Push(_Util::MakePair(prevX, curX));
1476 // Cannot determine a glyph extent
1478 outList.Push(_Util::MakePair(curX, curX));
1485 _Font::__GetTextExtentList(_TextBidiPropertyWithReorder& bidiProperty, _Util::AccumList<_Util::Pair<int, int> >& outList) const
1487 if (bidiProperty.length <= 0)
1494 _Util::AccumList<_Util::Pair<int, int> > tempList;
1500 int length = bidiProperty.length;
1502 _Font* pThis = const_cast <_Font*>(this);
1504 pThis->ApplyAttribute();
1506 const wchar_t* pReorderedText = bidiProperty.GetReorderedText();
1508 const wchar_t* pTextFragmentBegin = pReorderedText;
1509 const wchar_t* pTextFragmentEnd = pTextFragmentBegin + length;
1511 const wchar_t* pTextSegment = pTextFragmentBegin;
1513 _IFont* pBaseFont = pThis->__GetFont(*pTextSegment);
1515 _Util::AccumList<_TextFragment> textFragmentList;
1517 while (pTextSegment < pTextFragmentEnd)
1519 if (pBaseFont->CheckGlyph(*pTextSegment) == 0)
1521 _IFont* pFallbackFont = pThis->__GetFont(*pTextSegment);
1523 if (pBaseFont != pFallbackFont)
1525 textFragmentList.Push(_TextFragment(_Util::String(pTextFragmentBegin, pTextSegment - pTextFragmentBegin), pBaseFont));
1527 pTextFragmentBegin = pTextSegment;
1528 pBaseFont = pFallbackFont;
1535 textFragmentList.Push(_TextFragment(_Util::String(pTextFragmentBegin, pTextSegment - pTextFragmentBegin), pBaseFont));
1539 * for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.Begin(); textFragment != textFragmentList.End(); ++textFragment)
1542 * for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.End(); textFragment != textFragmentList.Begin(); )
1548 for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.Begin(); textFragment != textFragmentList.End(); ++textFragment)
1550 if (textFragment->pUsingFont == null || textFragment->textFragment.length <= 0)
1555 if (textFragment->pUsingFont != __pNativeFont)
1557 _IFont::Attrib fontAttrib;
1559 if (textFragment->pUsingFont->GetAttrib(fontAttrib))
1561 fontAttrib.size = __fontAttrib.size;
1562 fontAttrib.style = _IFont::STYLE_NONE;
1563 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
1564 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
1565 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
1567 textFragment->pUsingFont->SetAttrib(fontAttrib);
1571 Tizen::Base::Collection::ArrayListT<_IFont::Glyph *> glyphList;
1573 const wchar_t firstChar = *textFragment->textFragment.pStart;
1575 GUnicodeScript script = _TextBidiUtil::GetUnicodeScript(firstChar);
1576 // need to check if (script < 0 || script >= _sampleLanguageCount) ?
1578 textFragment->pUsingFont->GetGlyphList(textFragment->textFragment, glyphList, script);
1580 int count = glyphList.GetCount();
1582 for (int i = 0; i < count; i++)
1584 _IFont::Glyph *pGlyph = 0;
1586 glyphList.GetAt(i, pGlyph);
1588 // bug fixed in test case of L"\x9a8\x20\x981\x9a0\x635"
1589 //if (pGlyph->xAdvance == 0 && pGlyph->image.width == 0)
1596 xDest += pGlyph->xAdvance.ToInt();
1597 yDest += pGlyph->yAdvance.ToInt();
1599 tempList.Push(_Util::MakePair(prevX, xDest));
1600 outList.Push(_Util::MakePair(-1, -1));
1603 IEnumeratorT<_IFont::Glyph*>* pEnum = glyphList.GetEnumeratorN();
1607 while (pEnum->MoveNext() == E_SUCCESS)
1609 _IFont::Glyph* pGlyph;
1611 pEnum->GetCurrent(pGlyph);
1612 pBaseFont->UnloadGlyph(&pGlyph);
1620 if (bidiProperty.pBidiIndex)
1622 // Reorder list by using BIDI index
1623 typedef _Util::Pair<int, int> Gap;
1624 typedef _Util::AccumList<Gap> GapList;
1626 GapList::Iterator dstBegin = outList.Begin();
1630 if (bidiProperty.length == int(tempList.Size()))
1632 for (GapList::ConstIterator src = tempList.Begin(); src != tempList.End(); ++src)
1634 *(dstBegin + bidiProperty.pBidiIndex[index++]) = *src;
1637 else if (bidiProperty.length > int(tempList.Size()))
1639 _TextBidiUtil::GetReorderedIndexList(bidiProperty, tempList, outList);
1641 else // if (bidiProperty.length < tempList.Size())
1643 // under development
1644 for (GapList::ConstIterator src = tempList.Begin(); src != tempList.End() && index < bidiProperty.length; ++src)
1646 *(dstBegin + bidiProperty.pBidiIndex[index++]) = *src;
1652 typedef _Util::Pair<int, int> Gap;
1653 typedef _Util::AccumList<Gap> GapList;
1655 GapList::Iterator dst = outList.Begin();
1656 GapList::Iterator dstEnd = outList.End();
1658 GapList::ConstIterator src = tempList.Begin();
1659 GapList::ConstIterator srcEnd = tempList.End();
1661 for (; (src != srcEnd) && (dst != dstEnd); ++src, ++dst)
1671 _Font::GetTextExtentList(const _Util::String& text, _Util::AccumList<_Util::Pair<int, int> >& outList) const
1673 if (text.pStart == null || text.length <= 0)
1679 _TextBidiPropertyWithReorder bidiProperty(text.pStart, text.length, _Util::Convert<TextBidiHint, _TextBidiProperty::BidiHint>(_GetTextBidiHint()));
1681 if (bidiProperty.HasComplexText())
1683 return this->__GetTextExtentList(bidiProperty, outList);
1687 return this->__GetTextExtentList(text, outList);
1694 _Font::SetSize(_Util::FixedPoint26_6 pcSize)
1696 __UpdateFontAttribute(__fontAttrib.style, pcSize);
1702 _Font::SetStyle(int style)
1704 __fontAttrib.style = style;
1710 _Font::GetStyle(void) const
1712 return __fontAttrib.style;
1715 _Util::FixedPoint26_6
1716 _Font::GetLeading(void) const
1718 return __fontAttrib.maxHeight;
1722 _Font::__DrawText(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length)
1724 SysTryReturnResult(NID_GRP, canvas.__pScratchPad != null, E_INVALID_ARG, "A canvas is invalid");
1726 const wchar_t* pText = text.GetPointer() + startIndex;
1728 bool rtn = this->ApplyAttribute();
1729 SysTryReturn(NID_GRP, rtn, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fails to apply font attribute.");
1731 _Util::ScratchPad <SystemPixel>& scratchPad = *canvas.__pScratchPad;
1732 scratchPad.RegisterFillRect(_RasterOp::FnFillRectFont32Bit);
1734 Rectangle clipBounds;
1735 canvas.__GetClipBounds(clipBounds);
1737 int xDest = point.x;
1738 int yDest = point.y;
1739 int startX = point.x;
1741 int italicSpace = 0;
1743 int clipX1 = clipBounds.x;
1744 int clipY1 = clipBounds.y;
1745 int clipX2 = clipX1 + clipBounds.width;
1746 int clipY2 = clipY1 + clipBounds.height;
1750 wchar_t leftChar = 0;
1751 _IFont::Glyph* pFontGlyphData = 0;
1753 _IFont::SizeProperty sizeProperty;
1754 rtn = this->GetFontSizeProperty(sizeProperty);
1755 SysTryReturn(NID_GRP, rtn, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to get font sizeProperty.");
1757 // need to revise y value, because _IFont is based on the baseline
1759 if (canvas.__textOrigin == TEXT_ORIGIN_LEFT_TOP)
1761 yDest += sizeProperty.ascender.ToInt();
1764 charHeight = sizeProperty.ascender.ToInt() - sizeProperty.descender.ToInt();
1766 if (this->GetStyle() & FONT_STYLE_ITALIC)
1768 italicSpace = (sizeProperty.ascender.ToInt() * 2) >> 4;
1772 _IFont::Property property;
1773 GET_FONT_PROPERTY(property, false);
1775 if (__fontAttrib.style & FONT_STYLE_BOLD && property.weightClass < _MEDIUM_FONT_BOLD_WEIGHT)
1777 _IFont::Attrib attr;
1778 this->GetAttrib(attr);
1779 boldSpace = static_cast<int>(attr.boldWeight.ToFloat() + 0.5f);
1782 unsigned long canvasFgColor = canvas.__fgColor;
1784 _TextBidiPropertyWithReorder bidiProperty(pText, length, _Util::Convert<TextBidiHint, _TextBidiProperty::BidiHint>(_GetTextBidiHint()));
1786 if (bidiProperty.HasComplexText())
1788 const wchar_t* pReorderedText = bidiProperty.GetReorderedText();
1790 const wchar_t* pTextFragmentBegin = pReorderedText;
1791 const wchar_t* pTextFragmentEnd = pTextFragmentBegin + length;
1793 const wchar_t* pTextSegment = pTextFragmentBegin;
1795 _IFont* pBaseFont = this->__GetFont(*pTextSegment);
1797 _Util::AccumList<_TextFragment> textFragmentList;
1799 while (pTextSegment < pTextFragmentEnd)
1801 if (pBaseFont->CheckGlyph(*pTextSegment) == 0)
1803 _IFont* pFallbackFont = this->__GetFont(*pTextSegment);
1805 if (pBaseFont != pFallbackFont)
1807 textFragmentList.Push(_TextFragment(_Util::String(pTextFragmentBegin, pTextSegment - pTextFragmentBegin), pBaseFont));
1809 pTextFragmentBegin = pTextSegment;
1810 pBaseFont = pFallbackFont;
1817 textFragmentList.Push(_TextFragment(_Util::String(pTextFragmentBegin, pTextSegment - pTextFragmentBegin), pBaseFont));
1821 * for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.Begin(); textFragment != textFragmentList.End(); ++textFragment)
1824 * for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.End(); textFragment != textFragmentList.Begin(); )
1830 for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.Begin(); textFragment != textFragmentList.End(); ++textFragment)
1832 if (textFragment->pUsingFont == null || textFragment->textFragment.length <= 0)
1837 if (textFragment->pUsingFont != __pNativeFont)
1839 _IFont::Attrib fontAttrib;
1841 if (textFragment->pUsingFont->GetAttrib(fontAttrib))
1843 fontAttrib.size = __fontAttrib.size;
1844 fontAttrib.style = _IFont::STYLE_NONE;
1845 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
1846 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
1847 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
1849 textFragment->pUsingFont->SetAttrib(fontAttrib);
1853 Tizen::Base::Collection::ArrayListT<_IFont::Glyph *> glyphList;
1855 const wchar_t firstChar = *textFragment->textFragment.pStart;
1857 GUnicodeScript script = _TextBidiUtil::GetUnicodeScript(firstChar);
1859 textFragment->pUsingFont->GetGlyphList(textFragment->textFragment, glyphList, script);
1860 // need to check if (script < 0 || script >= _sampleLanguageCount) ?
1862 int count = glyphList.GetCount();
1864 for (int i = 0; i < count; i++)
1867 static int s_index = 0;
1868 const unsigned long COLOR[6] =
1877 unsigned long canvasFgColor = COLOR[s_index++ % 6];
1880 typedef unsigned long TPixel;
1881 _IFont::Glyph *pGlyph = 0;
1883 TPixel srcR, srcG, srcB, srcA;
1884 TPixel dstR, dstG, dstB, dstA;
1886 srcA = (canvasFgColor >> 24) & 0xFF;
1887 srcA += (srcA >> 7);
1888 srcR = (canvasFgColor >> 16) & 0xFF;
1889 srcG = (canvasFgColor >> 8) & 0xFF;
1890 srcB = (canvasFgColor) & 0xFF;
1892 SystemPixel* pBufferStartAddr = null;
1895 scratchPad.GetBuffer(pBufferStartAddr, bufferPitch);
1897 glyphList.GetAt(i, pGlyph);
1899 if (!_TextBidiUtil::IsTextBidiBaseLtr())
1901 xDest -= pGlyph->xAdvance.ToInt();
1902 yDest -= pGlyph->yAdvance.ToInt();
1905 for (int h = 0; h < pGlyph->image.height; h++)
1907 int y = yDest - pGlyph->yOffset.ToInt() + h;
1919 TPixel* pDest32 = pBufferStartAddr + y * bufferPitch + xDest + pGlyph->xOffset.ToInt();
1921 for (int w = 0; w < pGlyph->image.width; w++)
1923 int x = xDest + pGlyph->xOffset.ToInt() + w;
1936 unsigned long alpha = (unsigned long) (pGlyph->image.pBitmap[h * pGlyph->image.bytesPerLine + w]);
1940 // equivalent to scratchPad.FillRect(x, y, 1, 1, fgColor, alpha);
1941 alpha = (alpha * srcA) >> 8;
1942 alpha += (alpha >> 7);
1944 dstA = (*pDest32 >> 24) & 0xFF;
1945 dstR = (*pDest32 >> 16) & 0xFF;
1946 dstG = (*pDest32 >> 8) & 0xFF;
1947 dstB = (*pDest32) & 0xFF;
1949 dstA = BLEND_ALPHA_COMPONEMT(alpha, dstA);
1950 dstR = (dstR + (((srcR - dstR) * alpha) >> 8)) & 0xFF;
1951 dstG = (dstG + (((srcG - dstG) * alpha) >> 8)) & 0xFF;
1952 dstB = (dstB + (((srcB - dstB) * alpha) >> 8)) & 0xFF;
1954 *pDest32 = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB;
1961 if (_TextBidiUtil::IsTextBidiBaseLtr())
1963 xDest += pGlyph->xAdvance.ToInt();
1964 yDest += pGlyph->yAdvance.ToInt();
1968 IEnumeratorT<_IFont::Glyph*>* pEnum = glyphList.GetEnumeratorN();
1972 while (pEnum->MoveNext() == E_SUCCESS)
1974 _IFont::Glyph* pGlyph;
1976 pEnum->GetCurrent(pGlyph);
1977 pBaseFont->UnloadGlyph(&pGlyph);
1986 while (*pText && --length >= 0)
1988 // find out proper native font
1989 _IFont* pFont = this->__GetFont(*pText);
1996 if (pFont != __pNativeFont)
1998 _IFont::Attrib fontAttrib;
1999 bool rtn = pFont->GetAttrib(fontAttrib);
2000 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to get font attribute");
2002 fontAttrib.size = __fontAttrib.size;
2003 fontAttrib.style = _IFont::STYLE_NONE;
2004 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
2005 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
2006 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
2008 rtn = pFont->SetAttrib(fontAttrib);
2009 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to set font attribute");
2012 _IFont::Property property;
2013 pFont->GetFontProperty(property);
2015 unsigned long fgColor = (canvas.__applyEmoji && pFont->IsEmoji()) ? GetPredefinedColor(*pText, canvasFgColor) : canvasFgColor;
2019 if (pFont->GetKerning(leftChar, *pText, xVec, yVec))
2025 bool rtn = pFont->LoadGlyph(*pText++, &pFontGlyphData);
2032 typedef unsigned long TPixel;
2034 TPixel srcA = (fgColor >> 24) & 0xFF;
2035 srcA += (srcA >> 7);
2037 TPixel srcR = (fgColor >> 16) & 0xFF;
2038 TPixel srcG = (fgColor >> 8) & 0xFF;
2039 TPixel srcB = (fgColor) & 0xFF;
2041 SystemPixel* pBufferStartAddr = null;
2042 int bufferPitch = 0;
2044 scratchPad.GetBuffer(pBufferStartAddr, bufferPitch);
2046 for (int h = 0; h < pFontGlyphData->image.height; h++)
2048 int y = yDest - pFontGlyphData->yOffset.ToInt() + h;
2060 TPixel* pDest32 = pBufferStartAddr + y * bufferPitch + xDest + pFontGlyphData->xOffset.ToInt();
2062 for (int w = 0; w < pFontGlyphData->image.width; w++)
2064 int x = xDest + pFontGlyphData->xOffset.ToInt() + w;
2077 unsigned long alpha = (unsigned long) (pFontGlyphData->image.pBitmap[h * pFontGlyphData->image.bytesPerLine + w]);
2081 // equivalent to scratchPad.FillRect(x, y, 1, 1, fgColor, alpha);
2082 alpha = (alpha * srcA) >> 8;
2083 alpha += (alpha >> 7);
2085 TPixel dstA = (*pDest32 >> 24) & 0xFF;
2086 TPixel dstR = (*pDest32 >> 16) & 0xFF;
2087 TPixel dstG = (*pDest32 >> 8) & 0xFF;
2088 TPixel dstB = (*pDest32) & 0xFF;
2090 dstA = BLEND_ALPHA_COMPONEMT(alpha, dstA);
2091 dstR = (dstR + (((srcR - dstR) * alpha) >> 8)) & 0xFF;
2092 dstG = (dstG + (((srcG - dstG) * alpha) >> 8)) & 0xFF;
2093 dstB = (dstB + (((srcB - dstB) * alpha) >> 8)) & 0xFF;
2095 *pDest32 = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB;
2102 xDest += pFontGlyphData->xAdvance.ToInt() + __fontAttrib.charSpace + italicSpace + boldSpace;
2103 yDest += pFontGlyphData->yAdvance.ToInt();
2105 leftChar = *(pText - 1);
2107 pFont->UnloadGlyph(&pFontGlyphData);
2112 if (this->IsUnderlined() || this->IsStrikeOut())
2115 int thick = this->GetLineThickness();
2117 if (canvas.__textOrigin == TEXT_ORIGIN_LEFT_TOP)
2119 y = point.y + charHeight - 1;
2123 y = point.y - sizeProperty.descender.ToInt() - 1;
2126 xDest -= this->GetCharSpace();
2128 if (this->IsUnderlined())
2130 canvas.FillRectangle(canvasFgColor, Rectangle(startX, y - thick, xDest - startX, thick));
2133 if (this->IsStrikeOut())
2135 y -= charHeight / 2;
2136 canvas.FillRectangle(canvasFgColor, Rectangle(startX, y - thick, xDest - startX, thick));
2140 scratchPad.RegisterFillRect(null);
2146 #undef BLEND_ALPHA_COMPONEMT
2149 _Font::__DrawText(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length, const Color& outlineColor)
2151 unsigned long textColor = canvas.__fgColor;
2152 bool applyEmoji = canvas.__applyEmoji;
2154 //sunmi557.shin: draw border of font
2155 canvas.__fgColor = outlineColor.GetRGB32();
2156 canvas.__applyEmoji = false;
2158 this->__DrawText(canvas, Point(point.x - 1, point.y), text, startIndex, length);
2159 this->__DrawText(canvas, Point(point.x + 1, point.y), text, startIndex, length);
2160 this->__DrawText(canvas, Point(point.x, point.y - 1), text, startIndex, length);
2161 this->__DrawText(canvas, Point(point.x, point.y + 1), text, startIndex, length);
2163 //sunmi557.shin: draw original shape of font
2164 canvas.__applyEmoji = applyEmoji;
2165 canvas.__fgColor = textColor;
2167 this->__DrawText(canvas, point, text, startIndex, length);
2173 _Font::SetAttrib(const _IFont::Attrib& fontAttrib)
2175 return __pNativeFont->SetAttrib(fontAttrib);
2179 _Font::GetAttrib(_IFont::Attrib& fontAttrib) const
2181 return __pNativeFont->GetAttrib(fontAttrib);
2185 _Font::GetKerning(unsigned long character1, unsigned long character2, long& xVector, long& yVector) const
2187 return __pNativeFont->GetKerning(character1, character2, xVector, yVector);
2191 _Font::GetFontSizeProperty(_IFont::SizeProperty& sizeProperty) const
2193 return __pNativeFont->GetFontSizeProperty(sizeProperty);
2197 _Font::LoadGlyph(unsigned long character, _IFont::Glyph** ppFontGlyphData)
2199 // note! we assume that the font attribute has been already applied on _IFont
2202 // if not, loading glyph (character/size/style) and caching it
2203 rtn = __pNativeFont->LoadGlyph(character, ppFontGlyphData);
2204 SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to load glyph data");
2206 // return cached glyph
2211 _Font::UnloadGlyph(_IFont::Glyph** ppFontGlyphData)
2213 return __pNativeFont->UnloadGlyph(ppFontGlyphData);
2217 _Font::CheckGlyph(unsigned long character)
2219 return __pNativeFont->CheckGlyph(character);
2223 _Font::__UpdateFontAttribute(int style, _Util::FixedPoint26_6 pcSize)
2225 __fontAttrib.style = style;
2226 __fontAttrib.size = pcSize;
2227 __fontAttrib.lineThickness = pcSize.ToInt() > 0 ? (pcSize.ToInt() / 24) + 1 : 1;
2229 _IFont::SizeProperty sizeProperty;
2230 bool getProperty = false;
2232 if (this->ApplyAttribute())
2234 getProperty = __pNativeFont->GetFontSizeProperty(sizeProperty);
2239 __fontAttrib.maxWidth = sizeProperty.maxWidth;
2240 __fontAttrib.maxHeight = sizeProperty.maxHeight;
2241 __fontAttrib.ascender = sizeProperty.ascender;
2242 __fontAttrib.descender = sizeProperty.descender;
2246 // if failed to get property above, each property should be remained as default: -1
2247 SysLog(NID_GRP, "[] Failed to get font attribute from native font");
2249 __fontAttrib.maxWidth.Reset(0);
2250 __fontAttrib.maxHeight.Reset(0);
2251 __fontAttrib.ascender.Reset(0);
2252 __fontAttrib.descender.Reset(0);
2257 _Font::__DrawTextLastFallback(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length)
2263 _Font::__DrawTextDefault(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length)
2265 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
2266 result r = mgr.GetDefaultSystemFont().__DrawText(canvas, point, text, startIndex, length);
2267 SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Failed to draw default system font", GetErrorMessage(r));
2272 _Font::__DrawTextLastFallback(canvas, point, text, startIndex, length);
2277 _Font::__DrawTextDefault(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length, const Color& outlineColor)
2279 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
2280 result r = mgr.GetDefaultSystemFont().__DrawText(canvas, point, text, startIndex, length, outlineColor);
2281 SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Failed to draw default system font", GetErrorMessage(r));
2286 _Font::__DrawTextLastFallback(canvas, point, text, startIndex, length);
2292 _Font::DrawText(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length)
2294 if (canvas.__pPriorityFont)
2296 return canvas.__pPriorityFont->__DrawText(canvas, point, text, startIndex, length);
2298 else if (canvas.__pFont)
2300 return canvas.__pFont->__DrawText(canvas, point, text, startIndex, length);
2304 return _Font::__DrawTextDefault(canvas, point, text, startIndex, length);
2309 _Font::DrawText(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length, const Color& outlineColor)
2311 if (canvas.__pPriorityFont)
2313 return canvas.__pPriorityFont->__DrawText(canvas, point, text, startIndex, length, outlineColor);
2315 else if (canvas.__pFont)
2317 return canvas.__pFont->__DrawText(canvas, point, text, startIndex, length, outlineColor);
2321 return _Font::__DrawTextDefault(canvas, point, text, startIndex, length, outlineColor);
2328 _Font::GetInstance(_FontImpl& font)
2330 return (&font != null) ? font._pNativeFont : null;
2334 _Font::GetInstance(const _FontImpl& font)
2336 return (&font != null) ? font._pNativeFont : null;
2340 _Font::__GetFont(wchar_t character)
2342 //------------------------------------------------------
2344 // 1. check if this font has a requested glyph
2346 //------------------------------------------------------
2347 unsigned long idx = __pNativeFont->CheckGlyph(character);
2351 return __pNativeFont;
2354 //------------------------------------------------------
2356 // 1-2. check if this glyph is in the fallback list.
2358 //------------------------------------------------------
2359 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
2360 _IFont::FontMapT* pFallbackFontMap = __pNativeFont->GetFallbackMap();
2362 #ifdef USE_HASHMAP_FOR_FONT
2363 std::auto_ptr<IMapEnumeratorT<_Util::WString, _FontRsrcManager::SharedFontResource> > enumerator(pFallbackFontMap->GetMapEnumeratorN());
2365 while (enumerator->MoveNext() == E_SUCCESS)
2367 _FontRsrcManager::SharedFontResource pTempFont;
2369 if (enumerator->GetValue(pTempFont) == E_SUCCESS)
2371 _Util::WString key(L"");
2372 result r = enumerator->GetKey(key);
2376 if (mgr.SearchFont(key))
2378 if (pTempFont.get()->CheckGlyph(character) > 0)
2380 return pTempFont.get();
2385 pFallbackFontMap->Remove(key);
2391 for (_FontRsrcManager::FontMapT::const_iterator fontIterator = pFallbackFontMap->begin(); fontIterator != pFallbackFontMap->end(); ++fontIterator)
2393 if (fontIterator->second != null)
2395 if (fontIterator->second->CheckGlyph(character) > 0)
2397 return fontIterator->second.get();
2403 //------------------------------------------------------
2405 // 2. Get fallback font list via fontconfig
2407 //------------------------------------------------------
2408 Tizen::Base::Collection::ArrayListT<String> fileList;
2409 bool rtn = __GetFallbackFontFileList(character, fileList);
2413 // if failed find out fallback font,
2414 // just use this instance for drawing something for unknown glyph
2415 return __pNativeFont;
2418 //------------------------------------------------------
2420 // 3. try to find a font having a requested glyph
2422 //------------------------------------------------------
2424 _IFont* pFallbackFont = null;
2426 _FontRsrcManager::SharedFontResource out;
2428 int count = fileList.GetCount();
2429 result r = E_FAILURE;
2431 for (int i = 0; i < count; i++)
2433 fileList.GetAt(i, fontName);
2435 if (fontName.IsEmpty())
2440 r = mgr.GetTempFont(fontName, __fontAttrib.style, __fontAttrib.size, out);
2444 unsigned long idx = out.get()->CheckGlyph(character);
2448 _Util::WString fontNameTemp(fontName.GetPointer());
2451 #ifdef USE_HASHMAP_FOR_FONT
2452 r = pFallbackFontMap->Add(fontNameTemp, out);
2454 if (r == E_OBJ_ALREADY_EXIST)
2456 pFallbackFont = out.get();
2460 SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
2462 pFallbackFontMap->push_back(std::make_pair(fontNameTemp, out));
2464 r = mgr.AddFont(fontNameTemp, out);
2465 SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
2467 pFallbackFont = out.get();
2473 return (pFallbackFont != null) ? pFallbackFont : __pNativeFont;
2476 // if failed find out fallback font,
2477 // just use this instance for drawing something for unknown glyph
2478 return __pNativeFont;
2482 _Font::__GetFallbackFontFileList(wchar_t character, Tizen::Base::Collection::IListT<String>& out)
2484 GUnicodeScript script = g_unichar_get_script(character);
2485 if (script < 0 || script >= _sampleLanguageCount)
2490 FcPattern* pPattern = null;
2491 FcFontSet* pSet = null;
2492 FcChar8* pName = null;
2493 FcResult res = FcResultNoMatch;
2494 const int fcWeight = (__fontAttrib.style & FONT_STYLE_BOLD) ? FC_WEIGHT_BOLD : FC_WEIGHT_REGULAR;
2496 // getting fallback font list
2497 pPattern = FcPatternBuild(NULL, FC_WEIGHT, FcTypeInteger, fcWeight, NULL);
2498 SysTryCatch(NID_GRP, pPattern, , E_SYSTEM, "[E_SYSTEM] Failed to FcPatternBuild()");
2500 FcPatternAddString(pPattern, FC_FAMILY, (FcChar8*)"Tizen");
2502 if (strncmp(SAMPLE_LANGUAGE_EMPTY, _SampleLanguages[script], strlen(SAMPLE_LANGUAGE_EMPTY) + 1) != 0)
2504 FcPatternAddString(pPattern, FC_LANG, (FcChar8*)_SampleLanguages[script]);
2507 FcConfigSubstitute(NULL, pPattern, FcMatchPattern);
2508 FcDefaultSubstitute(pPattern);
2511 pSet = FcFontSort(NULL, pPattern, FcTrue, NULL, &res);
2512 SysTryCatch(NID_GRP, pSet, , E_SYSTEM, "[E_SYSTEM] Failed to FcFontSort()");
2516 for (int i = 0; i < pSet->nfont; i++)
2518 if (FcPatternGetString(pSet->fonts[i], FC_FILE, 0, &pName) == FcResultMatch)
2520 out.Add(String((char*)pName));
2525 FcFontSetDestroy(pSet);
2526 FcPatternDestroy(pPattern);
2528 return (out.GetCount() > 0) ? true : false;
2532 FcFontSetDestroy(pSet);
2535 if (pPattern != null)
2537 FcPatternDestroy(pPattern);
2544 _Font::UpdateDefaultFont(const String& key)
2548 SysLog(NID_GRP, "Request to change the default font");
2550 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
2552 return mgr.ReloadDefaultSystemFont();
2558 }} // Tizen::Graphics