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] Memory allocation failed.");
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] Memory allocation failed.");
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] Memory allocation failed.");
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 _Util::CarveMagicKey(*this, __magicKey);
575 _Font::_Font(const _Font& obj)
578 this->__fontAttrib = obj.__fontAttrib;
579 this->__sharedFont = obj.__sharedFont;
581 _Util::CarveMagicKey(*this, __magicKey);
586 _Util::EraseMagicKey(*this, __magicKey);
590 _Font::Construct(int style, _Util::FixedPoint26_6 pcSize)
592 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
594 // use default system font
595 _FontRsrcManager::SharedFontResource out;
596 result r = mgr.GetFont(style, pcSize, out);
597 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get system default font", GetErrorMessage(r));
601 __UpdateFontAttribute(style, pcSize);
607 _Font::Construct(const Tizen::Base::String& fontName, int style, _Util::FixedPoint26_6 pcSize, bool isPathEnabled)
609 bool systemFont = false;
610 String appFontPath = L"";
611 result r = E_SUCCESS;
613 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
614 _FontRsrcManager::SharedFontResource out;
616 if (!Tizen::App::_AppInfo::IsOspCompat())
618 _Util::WString fontNameTemp(fontName.GetPointer());
619 _Util::WString appFontPathTemp(mgr.FindAppFontName(fontNameTemp));
620 appFontPath.Append(appFontPathTemp.c_str());
623 // check if user want to use a app font
624 if (!appFontPath.IsEmpty())
626 r = mgr.GetFont(appFontPath, style, pcSize, out);
627 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get app font", GetErrorMessage(r));
631 IList* pList = GetSystemFontListN();
636 for (idx = 0; idx < pList->GetCount(); idx++)
638 String* pName = static_cast <String*>(pList->GetAt(idx));
645 if (*pName == fontName)
652 pList->RemoveAll(true);
658 r = mgr.GetSystemFont(fontName, style, pcSize, out);
659 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get system font", GetErrorMessage(r));
661 else if (isPathEnabled)
663 r = mgr.GetFont(fontName, style, pcSize, out);
664 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get font", GetErrorMessage(r));
670 __UpdateFontAttribute(style, pcSize);
676 _Font::Construct(const Tizen::Base::ByteBuffer& fontData, int style, _Util::FixedPoint26_6 pcSize)
678 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
680 const byte* pBuffer = fontData.GetPointer();
681 int buffSize = fontData.GetLimit();
683 _FontRsrcManager::SharedFontResource out;
684 result r = mgr.GetFont(pBuffer, buffSize, style, pcSize, out);
685 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get system font", GetErrorMessage(r));
689 __UpdateFontAttribute(style, pcSize);
695 _Font::IsConstructed(void) const
697 return (__sharedFont.get() != null);
700 _Util::FixedPoint26_6
701 _Font::GetMaxHeight(void) const
703 return __fontAttrib.maxHeight;
706 _Util::FixedPoint26_6
707 _Font::GetMaxWidth(void) const
709 return __fontAttrib.maxWidth;
712 _Util::FixedPoint26_6
713 _Font::GetAscender(void) const
715 return __fontAttrib.ascender;
718 _Util::FixedPoint26_6
719 _Font::GetDescender(void) const
721 return __fontAttrib.descender;
725 _Font::GetLeftBear(wchar_t character, _Util::FixedPoint22_10& leftBear) const
729 _IFont::Glyph* pFontGlyphData = null;
730 LOAD_GLYPH_DATA_CONST(character, pFontGlyphData, E_SYSTEM);
732 // left bear is Glyph::xOffset, set it
733 leftBear = pFontGlyphData->xOffset;
735 UNLOAD_GLYPH_DATA_CONST(pFontGlyphData);
741 _Font::GetRightBear(wchar_t character, _Util::FixedPoint22_10& rightBear) const
745 _IFont::Glyph* pFontGlyphData = null;
746 LOAD_GLYPH_DATA_CONST(character, pFontGlyphData, E_SYSTEM);
748 // right bear is Glyph::xOffset + GlyphBitmap::width, set it
749 rightBear = pFontGlyphData->xOffset + _Util::FixedPoint22_10(pFontGlyphData->image.width);
751 UNLOAD_GLYPH_DATA_CONST(pFontGlyphData);
757 _Font::IsBold(void) const
759 return ((__fontAttrib.style & FONT_STYLE_BOLD) ? true : false);
763 _Font::IsItalic(void) const
765 return ((__fontAttrib.style & FONT_STYLE_ITALIC) ? true : false);
769 _Font::IsPlain(void) const
771 return ((__fontAttrib.style & FONT_STYLE_PLAIN) ? true : false);
775 _Font::IsStrikeOut(void) const
777 return __fontAttrib.strikeout;
781 _Font::IsUnderlined(void) const
783 return __fontAttrib.underline;
786 _Util::FixedPoint26_6
787 _Font::GetSize(void) const
789 return __fontAttrib.size;
793 _Font::SetXExpansion(_Util::FixedPoint26_6 xExpansion)
795 __fontAttrib.xExpansion = xExpansion;
801 _Font::SetStrikeOut(bool strikeout)
803 __fontAttrib.strikeout = strikeout;
807 _Font::SetUnderline(bool underline)
809 __fontAttrib.underline = underline;
813 _Font::SetCharSpace(int pc_space)
815 __fontAttrib.charSpace = pc_space;
819 _Font::GetCharSpace(void) const
821 return __fontAttrib.charSpace;
825 _Font::GetLineThickness(void) const
827 return __fontAttrib.lineThickness;
831 _Font::GetFaceName(void) const
833 _IFont::Property property;
834 GET_FONT_PROPERTY(property, String());
836 return ((property.pFamilyName) ? String(property.pFamilyName) : String());
839 Tizen::Base::Collection::IList*
840 _Font::GetSystemFontListN(void)
842 std::auto_ptr<ArrayList> pList(new (std::nothrow) Tizen::Base::Collection::ArrayList);
843 SysTryReturn(NID_GRP, pList.get(), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
845 result r = _GetSystemFontList(*pList);
846 SysTryReturn(NID_GRP, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
848 return pList.release();
852 _Font::GetFaceName(const Tizen::Base::String& filePath)
854 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
855 _FontRsrcManager::SharedFontResource out;
858 result r = mgr.GetTempFont(filePath, FONT_STYLE_PLAIN, _SYSTEM_DEFAULT_FONT_SIZE, out);
859 SysTryReturn(NID_GRP, r == E_SUCCESS, faceName, r, "[%s] Failed to get font", GetErrorMessage(r));
863 _IFont* pTempFont = out.get();
865 _IFont::Property property;
866 pTempFont->GetFontProperty(property);
867 faceName = String(property.pFamilyName);
874 _Font::GetNativeFont(void) const
876 return __pNativeFont;
883 _Font* pNativeFont = new (std::nothrow) _Font(*this);
884 SysTryReturn(NID_GRP, pNativeFont, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
891 _Font::ApplyAttribute()
893 _IFont::Attrib fontAttrib;
894 bool rtn = __pNativeFont->GetAttrib(fontAttrib);
895 SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to get font attribute");
897 fontAttrib.size = __fontAttrib.size;
898 fontAttrib.style = _IFont::STYLE_NONE;
899 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
900 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
901 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
902 fontAttrib.xExpansion = __fontAttrib.xExpansion;
903 rtn = __pNativeFont->SetAttrib(fontAttrib);
904 SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to set font attribute");
910 _Font::GetTextExtent(int width, const _Util::String& text, bool outline, int& count, Dimension& pcDim) const
912 if (text.pStart == null || text.length <= 0)
919 result r = this->__GetTextExtentEx(width, text, outline, count, pcDim);
926 _TextBidiPropertyWithReorder bidiProperty(text.pStart, text.length, _Util::Convert<TextBidiHint, _TextBidiProperty::BidiHint>(_GetTextBidiHint()));
928 if (bidiProperty.HasComplexText())
930 typedef _Util::AccumList<_Util::Pair<int, int> > GapList;
934 result r = this->__GetTextExtentList(bidiProperty, gapList);
943 int determinedCount = -1;
945 for (GapList::Iterator i = gapList.Begin(); i != gapList.End(); ++i)
947 left = (i->first < left) ? i->first : left;
948 right = (i->second > right) ? i->second : right;
950 if (determinedCount < 0 && i->first < width && i->second >= width)
952 if (i != gapList.Begin())
954 if (i - gapList.Begin() - 1 < text.length)
956 determinedCount = bidiProperty.pBidiIndex[i - gapList.Begin() - 1];
960 determinedCount = text.length;
965 determinedCount = bidiProperty.pBidiIndex[0];
970 if (right - left <= width)
972 pcDim.SetSize(right - left, __fontAttrib.size.ToInt());
975 else if (determinedCount > 0 && right - left > 0)
977 int expectedValue = width * text.length / (right - left);
978 int tolerance = _Util::Abs(expectedValue - determinedCount);
979 tolerance = (tolerance == 0) ? 2 : tolerance;
981 int tempCount = expectedValue <= determinedCount ? determinedCount + tolerance : determinedCount + (tolerance * 2);
982 tempCount = tempCount > text.length ? text.length : tempCount;
986 while (right - left > width)
988 _TextBidiPropertyWithReorder determinedBidiProperty(text.pStart, --tempCount, _Util::Convert<TextBidiHint, _TextBidiProperty::BidiHint>(_GetTextBidiHint()));
990 GapList determinedGapList;
992 result r = this->__GetTextExtentList(determinedBidiProperty, determinedGapList);
1002 for (GapList::Iterator i = determinedGapList.Begin(); i != determinedGapList.End(); ++i)
1004 left = (i->first < left) ? i->first : left;
1005 right = (i->second > right) ? i->second : right;
1009 pcDim.SetSize(right - left, __fontAttrib.size.ToInt());
1014 pcDim.SetSize(0, 0);
1022 return this->__GetTextExtent(width, text, outline, count, pcDim);
1029 _Font::__GetTextExtentEx(int width, const _Util::String& text, bool outline, int& count, Dimension& pcDim) const
1031 int preX1 = 0x7FFFFFFF;
1032 int preY1 = 0x7FFFFFFF;
1033 int preX2 = -0x7FFFFFFF;
1034 int preY2 = -0x7FFFFFFF;
1036 int x1 = 0x7FFFFFFF;
1037 int y1 = 0x7FFFFFFF;
1038 int x2 = -0x7FFFFFFF;
1039 int y2 = -0x7FFFFFFF;
1045 int italicSpace = 0;
1051 wchar_t leftChar = 0;
1053 _IFont::Glyph* pFontGlyphData = 0;
1055 _Font* pThis = const_cast <_Font*>(this);
1057 APPLY_ATTRIBUTE(E_SYSTEM);
1060 _IFont::SizeProperty sizeProperty;
1061 GET_FONT_SIZE_PROPERTY(sizeProperty, E_SYSTEM);
1063 if (__fontAttrib.style & FONT_STYLE_ITALIC)
1065 italicSpace = (sizeProperty.ascender.ToInt() * 2) >> 4;
1069 _IFont::Property property;
1070 GET_FONT_PROPERTY(property, false);
1072 if (__fontAttrib.style & FONT_STYLE_BOLD && property.weightClass < _MEDIUM_FONT_BOLD_WEIGHT)
1074 _IFont::Attrib attr;
1075 pThis->GetAttrib(attr);
1076 boldSpace = static_cast<int>(attr.boldWeight.ToFloat() + 0.5f);
1079 const wchar_t* pText = text.pStart;
1080 int length = text.length;
1082 while (*pText && --length >= 0)
1085 FriBidiCharType type = fribidi_get_bidi_type((FriBidiChar) *pText);
1087 GUnicodeScript script = g_unichar_get_script(*pText);
1089 if (FRIBIDI_IS_LETTER(type) && FRIBIDI_IS_RTL(type))
1093 else if (script == G_UNICODE_SCRIPT_DEVANAGARI || script == G_UNICODE_SCRIPT_BENGALI)
1099 // getting proper _Font instance for the specified text
1100 _IFont* pFont = pThis->__GetFont(*pText);
1102 if (pFont != __pNativeFont)
1104 _IFont::Attrib fontAttrib;
1105 bool rtn = pFont->GetAttrib(fontAttrib);
1106 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to get font attribute");
1108 fontAttrib.size = __fontAttrib.size;
1109 fontAttrib.style = _IFont::STYLE_NONE;
1110 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
1111 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
1112 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
1113 fontAttrib.xExpansion = __fontAttrib.xExpansion;
1114 rtn = pFont->SetAttrib(fontAttrib);
1115 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to set font attribute");
1120 if (pFont->GetKerning(leftChar, *pText, xVec, yVec))
1126 if (pFont->LoadGlyph(*pText++, &pFontGlyphData))
1128 int glyphBoundX1 = curX;
1129 int glyphBoundY1 = curY - pFontGlyphData->yOffset.ToInt();
1130 int glyphBoundX2 = glyphBoundX1 +
1131 ((pFontGlyphData->image.width <= 0) ? pFontGlyphData->xAdvance.ToInt()
1132 : (pFontGlyphData->xOffset.ToInt() + pFontGlyphData->image.width));
1133 int glyphBoundY2 = glyphBoundY1 + pFontGlyphData->image.height;
1135 #ifdef SYNCHRONIZATION_2_0
1136 // adjusting x2 bounds for synchronizing fuctionality with 2.0
1137 glyphBoundX2 = glyphBoundX1 + pFontGlyphData->xAdvance.ToInt() + italicSpace + boldSpace;
1147 _ExpandBounds(glyphBoundX1, glyphBoundY1, x1, y1, x2, y2);
1148 _ExpandBounds(glyphBoundX2, glyphBoundY1, x1, y1, x2, y2);
1149 _ExpandBounds(glyphBoundX1, glyphBoundY2, x1, y1, x2, y2);
1150 _ExpandBounds(glyphBoundX2, glyphBoundY2, x1, y1, x2, y2);
1152 #ifdef SYNCHRONIZATION_2_0
1153 curX += pFontGlyphData->xAdvance.ToInt() + __fontAttrib.charSpace + italicSpace + boldSpace;
1155 curX += pFontGlyphData->xAdvance.ToInt() + __fontAttrib.charSpace + boldSpace;
1157 curY += pFontGlyphData->yAdvance.ToInt();
1159 pFont->UnloadGlyph(&pFontGlyphData);
1161 // check end condition
1162 // TODO, shkim, BIDI need to be cared
1163 if ((x2 - x1) > width)
1174 leftChar = *(pText - 1);
1178 if (characters == 0)
1180 pcDim.SetSize(0, 0);
1185 SysTryCatch(NID_GRP, preX1 <= preX2 && preY1 <= preY2, pcDim.SetSize(0, 0); count = 0, E_SYSTEM, "[E_SYSTEM] Failed to calculate text extent");
1188 pcDim.width = preX2 - preX1;
1189 #ifdef SYNCHRONIZATION_2_0
1190 pcDim.height = __fontAttrib.size.ToInt();
1192 pcDim.height = preY2 - preY1;
1193 #endif // SYNCHRONIZATION_2_0
1202 _Font::__GetTextExtent(int width, const _Util::String& text, bool outline, int& count, Dimension& pcDim) const
1204 if (text.pStart == null)
1206 pcDim.SetSize(0, 0);
1207 SysTryReturn(NID_GRP, false, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The given string is invalid.");
1210 int preX1 = 0x7FFFFFFF;
1211 int preY1 = 0x7FFFFFFF;
1212 int preX2 = -0x7FFFFFFF;
1213 int preY2 = -0x7FFFFFFF;
1215 int x1 = 0x7FFFFFFF;
1216 int y1 = 0x7FFFFFFF;
1217 int x2 = -0x7FFFFFFF;
1218 int y2 = -0x7FFFFFFF;
1224 int italicSpace = 0;
1230 wchar_t leftChar = 0;
1232 _IFont::Glyph* pFontGlyphData = 0;
1234 if (text.length == 0)
1237 pcDim.SetSize(0, 0);
1241 _Font* pThis = const_cast <_Font*>(this);
1243 APPLY_ATTRIBUTE(E_SYSTEM);
1246 _IFont::SizeProperty sizeProperty;
1247 GET_FONT_SIZE_PROPERTY(sizeProperty, E_SYSTEM);
1249 if (__fontAttrib.style & FONT_STYLE_ITALIC)
1251 italicSpace = (sizeProperty.ascender.ToInt() * 2) >> 4;
1255 _IFont::Property property;
1256 GET_FONT_PROPERTY(property, false);
1258 if (__fontAttrib.style & FONT_STYLE_BOLD && property.weightClass < _MEDIUM_FONT_BOLD_WEIGHT)
1260 _IFont::Attrib attr;
1261 pThis->GetAttrib(attr);
1262 boldSpace = static_cast<int>(attr.boldWeight.ToFloat() + 0.5f);
1265 const wchar_t* pText = text.pStart;
1266 int length = text.length;
1268 while (*pText && --length >= 0)
1270 // getting proper _Font instance for the specified text
1271 _IFont* pFont = pThis->__GetFont(*pText);
1273 if (pFont != __pNativeFont)
1275 _IFont::Attrib fontAttrib;
1276 bool rtn = pFont->GetAttrib(fontAttrib);
1277 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to get font attribute");
1279 fontAttrib.size = __fontAttrib.size;
1280 fontAttrib.style = _IFont::STYLE_NONE;
1281 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
1282 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
1283 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
1284 fontAttrib.xExpansion = __fontAttrib.xExpansion;
1285 rtn = pFont->SetAttrib(fontAttrib);
1286 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to set font attribute");
1291 if (pFont->GetKerning(leftChar, *pText, xVec, yVec))
1297 if (pFont->LoadGlyph(*pText++, &pFontGlyphData))
1299 int glyphBoundX1 = curX;
1300 int glyphBoundY1 = curY - pFontGlyphData->yOffset.ToInt();
1301 int glyphBoundX2 = glyphBoundX1 +
1302 ((pFontGlyphData->image.width <= 0) ? pFontGlyphData->xAdvance.ToInt()
1303 : (pFontGlyphData->xOffset.ToInt() + pFontGlyphData->image.width));
1304 int glyphBoundY2 = glyphBoundY1 + pFontGlyphData->image.height;
1306 #ifdef SYNCHRONIZATION_2_0
1307 // adjusting x2 bounds for synchronizing fuctionality with 2.0
1308 glyphBoundX2 = glyphBoundX1 + pFontGlyphData->xAdvance.ToInt() + italicSpace + boldSpace;
1318 _ExpandBounds(glyphBoundX1, glyphBoundY1, x1, y1, x2, y2);
1319 _ExpandBounds(glyphBoundX2, glyphBoundY1, x1, y1, x2, y2);
1320 _ExpandBounds(glyphBoundX1, glyphBoundY2, x1, y1, x2, y2);
1321 _ExpandBounds(glyphBoundX2, glyphBoundY2, x1, y1, x2, y2);
1323 #ifdef SYNCHRONIZATION_2_0
1324 curX += pFontGlyphData->xAdvance.ToInt() + __fontAttrib.charSpace + italicSpace + boldSpace;
1326 curX += pFontGlyphData->xAdvance.ToInt() + __fontAttrib.charSpace + boldSpace;
1328 curY += pFontGlyphData->yAdvance.ToInt();
1330 pFont->UnloadGlyph(&pFontGlyphData);
1332 // check end condition
1333 // TODO, shkim, BIDI need to be cared
1334 if ((x2 - x1) > width)
1345 leftChar = *(pText - 1);
1349 if (characters == 0)
1351 pcDim.SetSize(0, 0);
1356 SysTryCatch(NID_GRP, preX1 <= preX2 && preY1 <= preY2, pcDim.SetSize(0, 0); count = 0, E_SYSTEM, "[E_SYSTEM] Failed to calculate text extent");
1359 pcDim.width = preX2 - preX1;
1360 #ifdef SYNCHRONIZATION_2_0
1361 pcDim.height = __fontAttrib.size.ToInt();
1363 pcDim.height = preY2 - preY1;
1364 #endif // SYNCHRONIZATION_2_0
1373 _Font::GetTextExtent(int width, const _Util::String& text, bool outline, const Tizen::Base::String& delimiter, int& count, Dimension& dim) const
1375 const wchar_t* pText = text.pStart;
1376 const wchar_t* pTextEnd = pText + text.length;
1378 while (pText < pTextEnd)
1380 if (*pText == 0x0D || *pText == 0x0A)
1389 return this->GetTextExtent(width, _Util::String(text.pStart, pTextEnd - text.pStart), outline, count, dim);
1393 _Font::__GetTextExtentList(const _Util::String& text, _Util::AccumList<_Util::Pair<int, int> >& outList) const
1395 SysAssert(text.pStart != null && text.length > 0);
1399 _Font* pThis = const_cast <_Font*>(this);
1401 APPLY_ATTRIBUTE(E_SYSTEM);
1403 int addingSpace = __fontAttrib.charSpace;
1405 #ifdef SYNCHRONIZATION_2_0
1407 _IFont::SizeProperty sizeProperty;
1409 GET_FONT_SIZE_PROPERTY(sizeProperty, E_SYSTEM);
1411 if (__fontAttrib.style & FONT_STYLE_ITALIC)
1413 addingSpace += (sizeProperty.ascender.ToInt() * 2) >> 4;
1418 _IFont::Property property;
1419 GET_FONT_PROPERTY(property, false);
1421 if (__fontAttrib.style & FONT_STYLE_BOLD && property.weightClass < _MEDIUM_FONT_BOLD_WEIGHT)
1423 _IFont::Attrib attr;
1425 if (pThis->GetAttrib(attr))
1427 addingSpace += static_cast<int>(attr.boldWeight.ToFloat() + 0.5f);
1433 wchar_t prevChar = 0;
1435 const wchar_t* pText = text.pStart;
1436 int length = text.length;
1440 while (*(++pText) && --length >= 0)
1442 _IFont* pFont = pThis->__GetFont(*pText);
1446 if (pFont != __pNativeFont)
1448 _IFont::Attrib fontAttrib;
1450 if (pFont->GetAttrib(fontAttrib))
1452 fontAttrib.size = __fontAttrib.size;
1453 fontAttrib.style = _IFont::STYLE_NONE;
1454 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
1455 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
1456 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
1457 fontAttrib.xExpansion = __fontAttrib.xExpansion;
1458 pFont->SetAttrib(fontAttrib);
1462 _IFont::Glyph* pFontGlyphData = 0;
1464 if (pFont->LoadGlyph(*pText, &pFontGlyphData))
1466 // When LoadGlyph fails continuously in the original code, there is a problem to check the kerning on the results of the previous prevChar
1472 if (pFont->GetKerning(prevChar, *pText, xVec, yVec))
1480 curX += pFontGlyphData->xAdvance.ToInt() + addingSpace;
1481 curY += pFontGlyphData->yAdvance.ToInt();
1483 pFont->UnloadGlyph(&pFontGlyphData);
1486 outList.Push(_Util::MakePair(prevX, curX));
1492 // Cannot determine a glyph extent
1494 outList.Push(_Util::MakePair(curX, curX));
1501 _Font::__GetTextExtentList(_TextBidiPropertyWithReorder& bidiProperty, _Util::AccumList<_Util::Pair<int, int> >& outList) const
1503 if (bidiProperty.length <= 0)
1510 _Util::AccumList<_Util::Pair<int, int> > tempList;
1516 int length = bidiProperty.length;
1518 _Font* pThis = const_cast <_Font*>(this);
1520 pThis->ApplyAttribute();
1522 const wchar_t* pReorderedText = bidiProperty.GetReorderedText();
1524 const wchar_t* pTextFragmentBegin = pReorderedText;
1525 const wchar_t* pTextFragmentEnd = pTextFragmentBegin + length;
1527 const wchar_t* pTextSegment = pTextFragmentBegin;
1529 _IFont* pBaseFont = pThis->__GetFont(*pTextSegment);
1531 _Util::AccumList<_TextFragment> textFragmentList;
1533 while (pTextSegment < pTextFragmentEnd)
1535 if (pBaseFont->CheckGlyph(*pTextSegment) == 0)
1537 _IFont* pFallbackFont = pThis->__GetFont(*pTextSegment);
1539 if (pBaseFont != pFallbackFont)
1541 textFragmentList.Push(_TextFragment(_Util::String(pTextFragmentBegin, pTextSegment - pTextFragmentBegin), pBaseFont));
1543 pTextFragmentBegin = pTextSegment;
1544 pBaseFont = pFallbackFont;
1551 textFragmentList.Push(_TextFragment(_Util::String(pTextFragmentBegin, pTextSegment - pTextFragmentBegin), pBaseFont));
1555 * for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.Begin(); textFragment != textFragmentList.End(); ++textFragment)
1558 * for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.End(); textFragment != textFragmentList.Begin(); )
1564 for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.Begin(); textFragment != textFragmentList.End(); ++textFragment)
1566 if (textFragment->pUsingFont == null || textFragment->textFragment.length <= 0)
1571 if (textFragment->pUsingFont != __pNativeFont)
1573 _IFont::Attrib fontAttrib;
1575 if (textFragment->pUsingFont->GetAttrib(fontAttrib))
1577 fontAttrib.size = __fontAttrib.size;
1578 fontAttrib.style = _IFont::STYLE_NONE;
1579 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
1580 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
1581 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
1582 fontAttrib.xExpansion = __fontAttrib.xExpansion;
1583 textFragment->pUsingFont->SetAttrib(fontAttrib);
1587 Tizen::Base::Collection::ArrayListT<_IFont::Glyph *> glyphList;
1589 const wchar_t firstChar = *textFragment->textFragment.pStart;
1591 GUnicodeScript script = _TextBidiUtil::GetUnicodeScript(firstChar);
1592 // need to check if (script < 0 || script >= _sampleLanguageCount) ?
1594 textFragment->pUsingFont->GetGlyphList(textFragment->textFragment, glyphList, script);
1596 int count = glyphList.GetCount();
1598 for (int i = 0; i < count; i++)
1600 _IFont::Glyph *pGlyph = 0;
1602 glyphList.GetAt(i, pGlyph);
1604 // bug fixed in test case of L"\x9a8\x20\x981\x9a0\x635"
1605 //if (pGlyph->xAdvance == 0 && pGlyph->image.width == 0)
1612 xDest += pGlyph->xAdvance.ToInt();
1613 yDest += pGlyph->yAdvance.ToInt();
1615 tempList.Push(_Util::MakePair(prevX, xDest));
1616 outList.Push(_Util::MakePair(-1, -1));
1619 IEnumeratorT<_IFont::Glyph*>* pEnum = glyphList.GetEnumeratorN();
1623 while (pEnum->MoveNext() == E_SUCCESS)
1625 _IFont::Glyph* pGlyph;
1627 pEnum->GetCurrent(pGlyph);
1628 pBaseFont->UnloadGlyph(&pGlyph);
1636 if (bidiProperty.pBidiIndex)
1638 // Reorder list by using BIDI index
1639 typedef _Util::Pair<int, int> Gap;
1640 typedef _Util::AccumList<Gap> GapList;
1642 GapList::Iterator dstBegin = outList.Begin();
1646 if (bidiProperty.length == int(tempList.Size()))
1648 for (GapList::ConstIterator src = tempList.Begin(); src != tempList.End(); ++src)
1650 *(dstBegin + bidiProperty.pBidiIndex[index++]) = *src;
1653 else if (bidiProperty.length > int(tempList.Size()))
1655 _TextBidiUtil::GetReorderedIndexList(bidiProperty, tempList, outList);
1657 else // if (bidiProperty.length < tempList.Size())
1659 // under development
1660 for (GapList::ConstIterator src = tempList.Begin(); src != tempList.End() && index < bidiProperty.length; ++src)
1662 *(dstBegin + bidiProperty.pBidiIndex[index++]) = *src;
1668 typedef _Util::Pair<int, int> Gap;
1669 typedef _Util::AccumList<Gap> GapList;
1671 GapList::Iterator dst = outList.Begin();
1672 GapList::Iterator dstEnd = outList.End();
1674 GapList::ConstIterator src = tempList.Begin();
1675 GapList::ConstIterator srcEnd = tempList.End();
1677 for (; (src != srcEnd) && (dst != dstEnd); ++src, ++dst)
1687 _Font::GetTextExtentList(const _Util::String& text, _Util::AccumList<_Util::Pair<int, int> >& outList) const
1689 if (text.pStart == null || text.length <= 0)
1695 _TextBidiPropertyWithReorder bidiProperty(text.pStart, text.length, _Util::Convert<TextBidiHint, _TextBidiProperty::BidiHint>(_GetTextBidiHint()));
1697 if (bidiProperty.HasComplexText())
1699 return this->__GetTextExtentList(bidiProperty, outList);
1703 return this->__GetTextExtentList(text, outList);
1710 _Font::SetSize(_Util::FixedPoint26_6 pcSize)
1712 __UpdateFontAttribute(__fontAttrib.style, pcSize);
1718 _Font::SetStyle(int style)
1720 __fontAttrib.style = style;
1726 _Font::GetStyle(void) const
1728 return __fontAttrib.style;
1731 _Util::FixedPoint26_6
1732 _Font::GetLeading(void) const
1735 return __fontAttrib.maxHeight;
1737 return __fontAttrib.ascender - __fontAttrib.descender + __fontAttrib.leading;
1742 _Font::__DrawText(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length)
1744 SysTryReturnResult(NID_GRP, canvas.__pScratchPad != null, E_INVALID_ARG, "A canvas is invalid");
1746 const wchar_t* pText = text.GetPointer() + startIndex;
1748 bool rtn = this->ApplyAttribute();
1749 SysTryReturn(NID_GRP, rtn, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fails to apply font attribute.");
1751 _Util::ScratchPad <SystemPixel>& scratchPad = *canvas.__pScratchPad;
1752 scratchPad.RegisterFillRect(_RasterOp::FnFillRectFont32Bit);
1754 Rectangle clipBounds;
1755 canvas.__GetClipBounds(clipBounds);
1757 int xDest = point.x;
1758 int yDest = point.y;
1759 int startX = point.x;
1761 int italicSpace = 0;
1763 int clipX1 = clipBounds.x;
1764 int clipY1 = clipBounds.y;
1765 int clipX2 = clipX1 + clipBounds.width;
1766 int clipY2 = clipY1 + clipBounds.height;
1770 wchar_t leftChar = 0;
1771 _IFont::Glyph* pFontGlyphData = 0;
1773 _IFont::SizeProperty sizeProperty;
1774 rtn = this->GetFontSizeProperty(sizeProperty);
1775 SysTryReturn(NID_GRP, rtn, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to get font sizeProperty.");
1777 // need to revise y value, because _IFont is based on the baseline
1779 if (canvas.__textOrigin == TEXT_ORIGIN_LEFT_TOP)
1781 yDest += sizeProperty.ascender.ToInt();
1784 charHeight = sizeProperty.ascender.ToInt() - sizeProperty.descender.ToInt();
1786 if (this->GetStyle() & FONT_STYLE_ITALIC)
1788 italicSpace = (sizeProperty.ascender.ToInt() * 2) >> 4;
1792 _IFont::Property property;
1793 GET_FONT_PROPERTY(property, false);
1795 if (__fontAttrib.style & FONT_STYLE_BOLD && property.weightClass < _MEDIUM_FONT_BOLD_WEIGHT)
1797 _IFont::Attrib attr;
1798 this->GetAttrib(attr);
1799 boldSpace = static_cast<int>(attr.boldWeight.ToFloat() + 0.5f);
1802 unsigned long canvasFgColor = canvas.__fgColor;
1804 _TextBidiPropertyWithReorder bidiProperty(pText, length, _Util::Convert<TextBidiHint, _TextBidiProperty::BidiHint>(_GetTextBidiHint()));
1806 if (bidiProperty.HasComplexText())
1808 const wchar_t* pReorderedText = bidiProperty.GetReorderedText();
1810 const wchar_t* pTextFragmentBegin = pReorderedText;
1811 const wchar_t* pTextFragmentEnd = pTextFragmentBegin + length;
1813 const wchar_t* pTextSegment = pTextFragmentBegin;
1815 _IFont* pBaseFont = this->__GetFont(*pTextSegment);
1817 _Util::AccumList<_TextFragment> textFragmentList;
1819 while (pTextSegment < pTextFragmentEnd)
1821 if (pBaseFont->CheckGlyph(*pTextSegment) == 0)
1823 _IFont* pFallbackFont = this->__GetFont(*pTextSegment);
1825 if (pBaseFont != pFallbackFont)
1827 textFragmentList.Push(_TextFragment(_Util::String(pTextFragmentBegin, pTextSegment - pTextFragmentBegin), pBaseFont));
1829 pTextFragmentBegin = pTextSegment;
1830 pBaseFont = pFallbackFont;
1837 textFragmentList.Push(_TextFragment(_Util::String(pTextFragmentBegin, pTextSegment - pTextFragmentBegin), pBaseFont));
1841 * for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.Begin(); textFragment != textFragmentList.End(); ++textFragment)
1844 * for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.End(); textFragment != textFragmentList.Begin(); )
1850 for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.Begin(); textFragment != textFragmentList.End(); ++textFragment)
1852 if (textFragment->pUsingFont == null || textFragment->textFragment.length <= 0)
1857 if (textFragment->pUsingFont != __pNativeFont)
1859 _IFont::Attrib fontAttrib;
1861 if (textFragment->pUsingFont->GetAttrib(fontAttrib))
1863 fontAttrib.size = __fontAttrib.size;
1864 fontAttrib.style = _IFont::STYLE_NONE;
1865 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
1866 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
1867 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
1868 fontAttrib.xExpansion = __fontAttrib.xExpansion;
1869 textFragment->pUsingFont->SetAttrib(fontAttrib);
1873 Tizen::Base::Collection::ArrayListT<_IFont::Glyph *> glyphList;
1875 const wchar_t firstChar = *textFragment->textFragment.pStart;
1877 GUnicodeScript script = _TextBidiUtil::GetUnicodeScript(firstChar);
1879 textFragment->pUsingFont->GetGlyphList(textFragment->textFragment, glyphList, script);
1880 // need to check if (script < 0 || script >= _sampleLanguageCount) ?
1882 int count = glyphList.GetCount();
1884 for (int i = 0; i < count; i++)
1887 static int s_index = 0;
1888 const unsigned long COLOR[6] =
1897 unsigned long canvasFgColor = COLOR[s_index++ % 6];
1900 typedef unsigned long TPixel;
1901 _IFont::Glyph *pGlyph = 0;
1903 TPixel srcR, srcG, srcB, srcA;
1904 TPixel dstR, dstG, dstB, dstA;
1906 srcA = (canvasFgColor >> 24) & 0xFF;
1907 srcA += (srcA >> 7);
1908 srcR = (canvasFgColor >> 16) & 0xFF;
1909 srcG = (canvasFgColor >> 8) & 0xFF;
1910 srcB = (canvasFgColor) & 0xFF;
1912 SystemPixel* pBufferStartAddr = null;
1915 scratchPad.GetBuffer(pBufferStartAddr, bufferPitch);
1917 glyphList.GetAt(i, pGlyph);
1919 if (!_TextBidiUtil::IsTextBidiBaseLtr())
1921 xDest -= pGlyph->xAdvance.ToInt();
1922 yDest -= pGlyph->yAdvance.ToInt();
1925 for (int h = 0; h < pGlyph->image.height; h++)
1927 int y = yDest - pGlyph->yOffset.ToInt() + h;
1939 TPixel* pDest32 = pBufferStartAddr + y * bufferPitch + xDest + pGlyph->xOffset.ToInt();
1941 for (int w = 0; w < pGlyph->image.width; w++)
1943 int x = xDest + pGlyph->xOffset.ToInt() + w;
1956 unsigned long alpha = (unsigned long) (pGlyph->image.pBitmap[h * pGlyph->image.bytesPerLine + w]);
1960 // equivalent to scratchPad.FillRect(x, y, 1, 1, fgColor, alpha);
1961 alpha = (alpha * srcA) >> 8;
1962 alpha += (alpha >> 7);
1964 dstA = (*pDest32 >> 24) & 0xFF;
1965 dstR = (*pDest32 >> 16) & 0xFF;
1966 dstG = (*pDest32 >> 8) & 0xFF;
1967 dstB = (*pDest32) & 0xFF;
1969 dstA = BLEND_ALPHA_COMPONEMT(alpha, dstA);
1970 dstR = (dstR + (((srcR - dstR) * alpha) >> 8)) & 0xFF;
1971 dstG = (dstG + (((srcG - dstG) * alpha) >> 8)) & 0xFF;
1972 dstB = (dstB + (((srcB - dstB) * alpha) >> 8)) & 0xFF;
1974 *pDest32 = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB;
1981 if (_TextBidiUtil::IsTextBidiBaseLtr())
1983 xDest += pGlyph->xAdvance.ToInt();
1984 yDest += pGlyph->yAdvance.ToInt();
1988 IEnumeratorT<_IFont::Glyph*>* pEnum = glyphList.GetEnumeratorN();
1992 while (pEnum->MoveNext() == E_SUCCESS)
1994 _IFont::Glyph* pGlyph;
1996 pEnum->GetCurrent(pGlyph);
1997 pBaseFont->UnloadGlyph(&pGlyph);
2006 while (*pText && --length >= 0)
2008 // find out proper native font
2009 _IFont* pFont = this->__GetFont(*pText);
2016 if (pFont != __pNativeFont)
2018 _IFont::Attrib fontAttrib;
2019 bool rtn = pFont->GetAttrib(fontAttrib);
2020 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to get font attribute");
2022 fontAttrib.size = __fontAttrib.size;
2023 fontAttrib.style = _IFont::STYLE_NONE;
2024 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
2025 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
2026 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
2027 fontAttrib.xExpansion = __fontAttrib.xExpansion;
2028 rtn = pFont->SetAttrib(fontAttrib);
2029 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to set font attribute");
2032 _IFont::Property property;
2033 pFont->GetFontProperty(property);
2035 unsigned long fgColor = (canvas.__applyEmoji && pFont->IsEmoji()) ? GetPredefinedColor(*pText, canvasFgColor) : canvasFgColor;
2039 if (pFont->GetKerning(leftChar, *pText, xVec, yVec))
2045 bool rtn = pFont->LoadGlyph(*pText++, &pFontGlyphData);
2052 typedef unsigned long TPixel;
2054 TPixel srcA = (fgColor >> 24) & 0xFF;
2055 srcA += (srcA >> 7);
2057 TPixel srcR = (fgColor >> 16) & 0xFF;
2058 TPixel srcG = (fgColor >> 8) & 0xFF;
2059 TPixel srcB = (fgColor) & 0xFF;
2061 SystemPixel* pBufferStartAddr = null;
2062 int bufferPitch = 0;
2064 scratchPad.GetBuffer(pBufferStartAddr, bufferPitch);
2066 for (int h = 0; h < pFontGlyphData->image.height; h++)
2068 int y = yDest - pFontGlyphData->yOffset.ToInt() + h;
2080 TPixel* pDest32 = pBufferStartAddr + y * bufferPitch + xDest + pFontGlyphData->xOffset.ToInt();
2082 for (int w = 0; w < pFontGlyphData->image.width; w++)
2084 int x = xDest + pFontGlyphData->xOffset.ToInt() + w;
2097 unsigned long alpha = (unsigned long) (pFontGlyphData->image.pBitmap[h * pFontGlyphData->image.bytesPerLine + w]);
2101 // equivalent to scratchPad.FillRect(x, y, 1, 1, fgColor, alpha);
2102 alpha = (alpha * srcA) >> 8;
2103 alpha += (alpha >> 7);
2105 TPixel dstA = (*pDest32 >> 24) & 0xFF;
2106 TPixel dstR = (*pDest32 >> 16) & 0xFF;
2107 TPixel dstG = (*pDest32 >> 8) & 0xFF;
2108 TPixel dstB = (*pDest32) & 0xFF;
2110 dstA = BLEND_ALPHA_COMPONEMT(alpha, dstA);
2111 dstR = (dstR + (((srcR - dstR) * alpha) >> 8)) & 0xFF;
2112 dstG = (dstG + (((srcG - dstG) * alpha) >> 8)) & 0xFF;
2113 dstB = (dstB + (((srcB - dstB) * alpha) >> 8)) & 0xFF;
2115 *pDest32 = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB;
2122 xDest += pFontGlyphData->xAdvance.ToInt() + __fontAttrib.charSpace + italicSpace + boldSpace;
2123 yDest += pFontGlyphData->yAdvance.ToInt();
2125 leftChar = *(pText - 1);
2127 pFont->UnloadGlyph(&pFontGlyphData);
2132 if (this->IsUnderlined() || this->IsStrikeOut())
2135 int thick = this->GetLineThickness();
2137 if (canvas.__textOrigin == TEXT_ORIGIN_LEFT_TOP)
2139 y = point.y + charHeight - 1;
2143 y = point.y - sizeProperty.descender.ToInt() - 1;
2146 xDest -= this->GetCharSpace();
2148 if (this->IsUnderlined())
2150 canvas.FillRectangle(canvasFgColor, Rectangle(startX, y - thick, xDest - startX, thick));
2153 if (this->IsStrikeOut())
2155 y -= charHeight / 2;
2156 canvas.FillRectangle(canvasFgColor, Rectangle(startX, y - thick, xDest - startX, thick));
2160 scratchPad.RegisterFillRect(null);
2166 #undef BLEND_ALPHA_COMPONEMT
2169 _Font::__DrawText(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length, const Color& outlineColor)
2171 unsigned long textColor = canvas.__fgColor;
2172 bool applyEmoji = canvas.__applyEmoji;
2174 //sunmi557.shin: draw border of font
2175 canvas.__fgColor = outlineColor.GetRGB32();
2176 canvas.__applyEmoji = false;
2178 this->__DrawText(canvas, Point(point.x - 1, point.y), text, startIndex, length);
2179 this->__DrawText(canvas, Point(point.x + 1, point.y), text, startIndex, length);
2180 this->__DrawText(canvas, Point(point.x, point.y - 1), text, startIndex, length);
2181 this->__DrawText(canvas, Point(point.x, point.y + 1), text, startIndex, length);
2183 //sunmi557.shin: draw original shape of font
2184 canvas.__applyEmoji = applyEmoji;
2185 canvas.__fgColor = textColor;
2187 this->__DrawText(canvas, point, text, startIndex, length);
2193 _Font::SetAttrib(const _IFont::Attrib& fontAttrib)
2195 return __pNativeFont->SetAttrib(fontAttrib);
2199 _Font::GetAttrib(_IFont::Attrib& fontAttrib) const
2201 return __pNativeFont->GetAttrib(fontAttrib);
2205 _Font::GetKerning(unsigned long character1, unsigned long character2, long& xVector, long& yVector) const
2207 return __pNativeFont->GetKerning(character1, character2, xVector, yVector);
2211 _Font::GetFontSizeProperty(_IFont::SizeProperty& sizeProperty) const
2213 return __pNativeFont->GetFontSizeProperty(sizeProperty);
2217 _Font::LoadGlyph(unsigned long character, _IFont::Glyph** ppFontGlyphData)
2219 // note! we assume that the font attribute has been already applied on _IFont
2222 // if not, loading glyph (character/size/style) and caching it
2223 rtn = __pNativeFont->LoadGlyph(character, ppFontGlyphData);
2224 SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to load glyph data");
2226 // return cached glyph
2231 _Font::UnloadGlyph(_IFont::Glyph** ppFontGlyphData)
2233 return __pNativeFont->UnloadGlyph(ppFontGlyphData);
2237 _Font::CheckGlyph(unsigned long character)
2239 return __pNativeFont->CheckGlyph(character);
2243 _Font::GetFontSizeFromMaxHeight(const _Util::FixedPoint26_6 expectedMaxHeight)
2245 return __pNativeFont->GetFontSizeFromMaxHeight(expectedMaxHeight);
2249 _Font::GetFontSizeFromMaxHeight(int style, const _Util::FixedPoint26_6 expectedMaxHeight)
2251 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
2252 _FontRsrcManager::SharedFontResource out;
2254 result r = mgr.GetFont(style, expectedMaxHeight, out);
2255 SysTryReturn(NID_GRP, r == E_SUCCESS, -1.0f, r, "[%s] Getting system default font failed.", GetErrorMessage(r));
2257 _IFont* pTempFont = out.get();
2259 return pTempFont->GetFontSizeFromMaxHeight(expectedMaxHeight);
2263 _Font::GetFontSizeFromMaxHeight(const Tizen::Base::String& fontName, int style, const _Util::FixedPoint26_6 expectedMaxHeight)
2265 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
2266 _FontRsrcManager::SharedFontResource out;
2268 result r = mgr.GetFont(fontName, style, expectedMaxHeight, out);
2269 SysTryReturn(NID_GRP, r == E_SUCCESS, -1.0f, r, "[%s] Getting font failed.", GetErrorMessage(r));
2271 _IFont* pTempFont = out.get();
2273 return pTempFont->GetFontSizeFromMaxHeight(expectedMaxHeight);
2277 _Font::__UpdateFontAttribute(int style, _Util::FixedPoint26_6 pcSize)
2279 __fontAttrib.style = style;
2280 __fontAttrib.size = pcSize;
2281 __fontAttrib.lineThickness = pcSize.ToInt() > 0 ? (pcSize.ToInt() / 24) + 1 : 1;
2283 _IFont::SizeProperty sizeProperty;
2284 bool getProperty = false;
2286 if (this->ApplyAttribute())
2288 getProperty = __pNativeFont->GetFontSizeProperty(sizeProperty);
2293 __fontAttrib.maxWidth = sizeProperty.maxWidth;
2294 __fontAttrib.maxHeight = sizeProperty.maxHeight;
2295 __fontAttrib.ascender = sizeProperty.ascender;
2296 __fontAttrib.descender = sizeProperty.descender;
2297 __fontAttrib.leading = sizeProperty.leading;
2301 // if failed to get property above, each property should be remained as default: -1
2302 SysLog(NID_GRP, "[] Failed to get font attribute from native font");
2304 __fontAttrib.maxWidth.Reset(0);
2305 __fontAttrib.maxHeight.Reset(0);
2306 __fontAttrib.ascender.Reset(0);
2307 __fontAttrib.descender.Reset(0);
2308 __fontAttrib.leading.Reset(0);
2313 _Font::__DrawTextLastFallback(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length)
2319 _Font::__DrawTextDefault(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length)
2321 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
2322 result r = mgr.GetDefaultSystemFont().__DrawText(canvas, point, text, startIndex, length);
2323 SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Failed to draw default system font", GetErrorMessage(r));
2328 _Font::__DrawTextLastFallback(canvas, point, text, startIndex, length);
2333 _Font::__DrawTextDefault(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length, const Color& outlineColor)
2335 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
2336 result r = mgr.GetDefaultSystemFont().__DrawText(canvas, point, text, startIndex, length, outlineColor);
2337 SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Failed to draw default system font", GetErrorMessage(r));
2342 _Font::__DrawTextLastFallback(canvas, point, text, startIndex, length);
2348 _Font::DrawText(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length)
2350 if (canvas.__pPriorityFont)
2352 return canvas.__pPriorityFont->__DrawText(canvas, point, text, startIndex, length);
2354 else if (canvas.__pFont)
2356 return canvas.__pFont->__DrawText(canvas, point, text, startIndex, length);
2360 return _Font::__DrawTextDefault(canvas, point, text, startIndex, length);
2365 _Font::DrawText(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length, const Color& outlineColor)
2367 if (canvas.__pPriorityFont)
2369 return canvas.__pPriorityFont->__DrawText(canvas, point, text, startIndex, length, outlineColor);
2371 else if (canvas.__pFont)
2373 return canvas.__pFont->__DrawText(canvas, point, text, startIndex, length, outlineColor);
2377 return _Font::__DrawTextDefault(canvas, point, text, startIndex, length, outlineColor);
2384 _Font::GetInstance(_FontImpl& font)
2386 return (&font != null) ? font._pNativeFont : null;
2390 _Font::GetInstance(const _FontImpl& font)
2392 return (&font != null) ? font._pNativeFont : null;
2396 _Font::__GetFont(wchar_t character)
2398 //------------------------------------------------------
2400 // 1. check if this font has a requested glyph
2402 //------------------------------------------------------
2403 unsigned long idx = __pNativeFont->CheckGlyph(character);
2407 return __pNativeFont;
2410 // Check the BlackList
2411 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
2413 if (mgr.SearchBlackList(character))
2415 return __pNativeFont;
2418 //------------------------------------------------------
2420 // 1-2. check if this glyph is in the fallback list.
2422 //------------------------------------------------------
2423 _IFont::FontMapT* pFallbackFontMap = __pNativeFont->GetFallbackMap();
2425 #ifdef USE_HASHMAP_FOR_FONT
2426 std::auto_ptr<IMapEnumeratorT<_Util::WString, _FontRsrcManager::SharedFontResource> > enumerator(pFallbackFontMap->GetMapEnumeratorN());
2428 while (enumerator->MoveNext() == E_SUCCESS)
2430 _FontRsrcManager::SharedFontResource pTempFont;
2432 if (enumerator->GetValue(pTempFont) == E_SUCCESS)
2434 _Util::WString key(L"");
2435 result r = enumerator->GetKey(key);
2439 if (mgr.SearchFont(key))
2441 if (pTempFont.get()->CheckGlyph(character) > 0)
2443 return pTempFont.get();
2448 pFallbackFontMap->Remove(key);
2454 for (_FontRsrcManager::FontMapT::const_iterator fontIterator = pFallbackFontMap->begin(); fontIterator != pFallbackFontMap->end(); ++fontIterator)
2456 if (fontIterator->second != null)
2458 if (fontIterator->second->CheckGlyph(character) > 0)
2460 return fontIterator->second.get();
2466 //------------------------------------------------------
2468 // 2. Get fallback font list via fontconfig
2470 //------------------------------------------------------
2471 Tizen::Base::Collection::ArrayListT<String> fileList;
2472 bool rtn = __GetFallbackFontFileList(character, fileList);
2476 // if failed find out fallback font,
2477 // just use this instance for drawing something for unknown glyph
2478 return __pNativeFont;
2481 //------------------------------------------------------
2483 // 3. try to find a font having a requested glyph
2485 //------------------------------------------------------
2487 _IFont* pFallbackFont = null;
2489 _FontRsrcManager::SharedFontResource out;
2491 int count = fileList.GetCount();
2492 result r = E_FAILURE;
2494 for (int i = 0; i < count; i++)
2496 fileList.GetAt(i, fontName);
2498 if (fontName.IsEmpty())
2503 r = mgr.GetTempFont(fontName, __fontAttrib.style, __fontAttrib.size, out);
2507 unsigned long idx = out.get()->CheckGlyph(character);
2511 _Util::WString fontNameTemp(fontName.GetPointer());
2514 #ifdef USE_HASHMAP_FOR_FONT
2515 r = pFallbackFontMap->Add(fontNameTemp, out);
2517 if (r == E_OBJ_ALREADY_EXIST)
2519 pFallbackFont = out.get();
2523 SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
2525 pFallbackFontMap->push_back(std::make_pair(fontNameTemp, out));
2527 r = mgr.AddFont(fontNameTemp, out);
2528 SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
2530 pFallbackFont = out.get();
2536 if (pFallbackFont == null)
2538 mgr.AddBlackList(character);
2540 return __pNativeFont;
2543 return pFallbackFont;
2546 // if failed find out fallback font,
2547 // just use this instance for drawing something for unknown glyph
2548 return __pNativeFont;
2552 _Font::__GetFallbackFontFileList(wchar_t character, Tizen::Base::Collection::IListT<String>& out)
2554 GUnicodeScript script = g_unichar_get_script(character);
2555 if (script < 0 || script >= _sampleLanguageCount)
2560 FcPattern* pPattern = null;
2561 FcFontSet* pSet = null;
2562 FcChar8* pName = null;
2563 FcResult res = FcResultNoMatch;
2564 const int fcWeight = (__fontAttrib.style & FONT_STYLE_BOLD) ? FC_WEIGHT_BOLD : FC_WEIGHT_REGULAR;
2566 // getting fallback font list
2567 pPattern = FcPatternBuild(NULL, FC_WEIGHT, FcTypeInteger, fcWeight, NULL);
2568 SysTryCatch(NID_GRP, pPattern, , E_SYSTEM, "[E_SYSTEM] Failed to FcPatternBuild()");
2570 FcPatternAddString(pPattern, FC_FAMILY, (FcChar8*)"Tizen");
2572 if (strncmp(SAMPLE_LANGUAGE_EMPTY, _SampleLanguages[script], strlen(SAMPLE_LANGUAGE_EMPTY) + 1) != 0)
2574 FcPatternAddString(pPattern, FC_LANG, (FcChar8*)_SampleLanguages[script]);
2577 FcConfigSubstitute(NULL, pPattern, FcMatchPattern);
2578 FcDefaultSubstitute(pPattern);
2581 pSet = FcFontSort(NULL, pPattern, FcTrue, NULL, &res);
2582 SysTryCatch(NID_GRP, pSet, , E_SYSTEM, "[E_SYSTEM] Failed to FcFontSort()");
2586 for (int i = 0; i < pSet->nfont; i++)
2588 if (FcPatternGetString(pSet->fonts[i], FC_FILE, 0, &pName) == FcResultMatch)
2590 out.Add(String((char*)pName));
2595 FcFontSetDestroy(pSet);
2596 FcPatternDestroy(pPattern);
2598 return (out.GetCount() > 0) ? true : false;
2602 FcFontSetDestroy(pSet);
2605 if (pPattern != null)
2607 FcPatternDestroy(pPattern);
2614 _Font::UpdateDefaultFont(const String& key)
2618 SysLog(NID_GRP, "Request to change the default font");
2620 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
2622 return mgr.ReloadDefaultSystemFont();
2628 }} // Tizen::Graphics