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 "FGrp_FontPrivate.h"
57 #include "util/FGrp_UtilTemplate.h"
59 //#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]);
465 _Util::String textFragment;
468 _TextFragment(const _Util::String& string, _IFont* pFont)
469 : textFragment(string)
478 namespace Tizen { namespace Graphics { namespace _Util
482 inline Tizen::Graphics::_TextBidiProperty::BidiHint Convert<Tizen::Graphics::TextBidiHint, Tizen::Graphics::_TextBidiProperty::BidiHint>(const Tizen::Graphics::TextBidiHint& bidiHint)
486 case TEXT_BIDI_HINT_LTR:
487 return _TextBidiProperty::BIDI_HINT_LTR;
488 case TEXT_BIDI_HINT_RTL:
489 return _TextBidiProperty::BIDI_HINT_RTL;
491 return _TextBidiProperty::BIDI_HINT_NONE;
495 }}} // Tizen::Graphics::_Util
498 namespace Tizen { namespace Graphics
506 _Util::CarveMagicKey(*this, __magicKey);
509 _Font::_Font(const _Font& obj)
512 this->__fontAttrib = obj.__fontAttrib;
513 this->__sharedFont = obj.__sharedFont;
515 _Util::CarveMagicKey(*this, __magicKey);
520 _Util::EraseMagicKey(*this, __magicKey);
524 _Font::Construct(int style, _Util::FixedPoint26_6 pcSize)
526 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
528 // use default system font
529 _FontRsrcManager::SharedFontResource out;
530 result r = mgr.GetFont(style, pcSize, out);
531 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get system default font", GetErrorMessage(r));
535 __UpdateFontAttribute(style, pcSize);
541 _Font::Construct(const Tizen::Base::String& fontName, int style, _Util::FixedPoint26_6 pcSize, bool isPathEnabled)
543 bool systemFont = false;
544 String appFontPath = L"";
545 result r = E_SUCCESS;
547 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
548 _FontRsrcManager::SharedFontResource out;
550 if (!Tizen::App::_AppInfo::IsOspCompat())
552 _Util::WString fontNameTemp(fontName.GetPointer());
553 _Util::WString appFontPathTemp(mgr.FindAppFontName(fontNameTemp));
554 appFontPath.Append(appFontPathTemp.c_str());
557 // check if user want to use a app font
558 if (!appFontPath.IsEmpty())
560 r = mgr.GetFont(appFontPath, style, pcSize, out);
561 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get app font", GetErrorMessage(r));
565 IList* pList = GetSystemFontListN();
570 for (idx = 0; idx < pList->GetCount(); idx++)
572 String* pName = static_cast <String*>(pList->GetAt(idx));
579 if (*pName == fontName)
586 pList->RemoveAll(true);
592 r = mgr.GetSystemFont(fontName, style, pcSize, out);
593 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get system font", GetErrorMessage(r));
595 else if (isPathEnabled)
597 r = mgr.GetFont(fontName, style, pcSize, out);
598 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get font", GetErrorMessage(r));
604 __UpdateFontAttribute(style, pcSize);
610 _Font::Construct(const Tizen::Base::ByteBuffer& fontData, int style, _Util::FixedPoint26_6 pcSize)
612 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
614 const byte* pBuffer = fontData.GetPointer();
615 int buffSize = fontData.GetLimit();
617 _FontRsrcManager::SharedFontResource out;
618 result r = mgr.GetFont(pBuffer, buffSize, style, pcSize, out);
619 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get system font", GetErrorMessage(r));
623 __UpdateFontAttribute(style, pcSize);
629 _Font::IsConstructed(void) const
631 return (__sharedFont.get() != null);
634 _Util::FixedPoint26_6
635 _Font::GetMaxHeight(void) const
637 return __fontAttrib.maxHeight;
640 _Util::FixedPoint26_6
641 _Font::GetMaxWidth(void) const
643 return __fontAttrib.maxWidth;
646 _Util::FixedPoint26_6
647 _Font::GetAscender(void) const
649 return __fontAttrib.ascender;
652 _Util::FixedPoint26_6
653 _Font::GetDescender(void) const
655 return __fontAttrib.descender;
659 _Font::GetLeftBear(wchar_t character, _Util::FixedPoint22_10& leftBear) const
663 _IFont::Glyph* pFontGlyphData = null;
664 LOAD_GLYPH_DATA_CONST(character, pFontGlyphData, E_SYSTEM);
666 // left bear is Glyph::xOffset, set it
667 leftBear = pFontGlyphData->xOffset;
669 UNLOAD_GLYPH_DATA_CONST(pFontGlyphData);
675 _Font::GetRightBear(wchar_t character, _Util::FixedPoint22_10& rightBear) const
679 _IFont::Glyph* pFontGlyphData = null;
680 LOAD_GLYPH_DATA_CONST(character, pFontGlyphData, E_SYSTEM);
682 // right bear is Glyph::xOffset + GlyphBitmap::width, set it
683 rightBear = pFontGlyphData->xOffset + _Util::FixedPoint22_10(pFontGlyphData->image.width);
685 UNLOAD_GLYPH_DATA_CONST(pFontGlyphData);
691 _Font::IsBold(void) const
693 return ((__fontAttrib.style & FONT_STYLE_BOLD) ? true : false);
697 _Font::IsItalic(void) const
699 return ((__fontAttrib.style & FONT_STYLE_ITALIC) ? true : false);
703 _Font::IsPlain(void) const
705 return ((__fontAttrib.style & FONT_STYLE_PLAIN) ? true : false);
709 _Font::IsStrikeOut(void) const
711 return __fontAttrib.strikeout;
715 _Font::IsUnderlined(void) const
717 return __fontAttrib.underline;
720 _Util::FixedPoint26_6
721 _Font::GetSize(void) const
723 return __fontAttrib.size;
727 _Font::SetXExpansion(_Util::FixedPoint26_6 xExpansion)
729 __fontAttrib.xExpansion = xExpansion;
735 _Font::SetStrikeOut(bool strikeout)
737 __fontAttrib.strikeout = strikeout;
741 _Font::SetUnderline(bool underline)
743 __fontAttrib.underline = underline;
747 _Font::SetCharSpace(int pc_space)
749 __fontAttrib.charSpace = pc_space;
753 _Font::GetCharSpace(void) const
755 return __fontAttrib.charSpace;
759 _Font::GetLineThickness(void) const
761 return __fontAttrib.lineThickness;
765 _Font::GetFaceName(void) const
767 _IFont::Property property;
768 GET_FONT_PROPERTY(property, String());
770 return ((property.pFamilyName) ? String(property.pFamilyName) : String());
773 Tizen::Base::Collection::IList*
774 _Font::GetSystemFontListN(void)
776 std::auto_ptr<ArrayList> pList(new (std::nothrow) Tizen::Base::Collection::ArrayList);
777 SysTryReturn(NID_GRP, pList.get(), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
779 result r = _GetSystemFontList(*pList);
780 SysTryReturn(NID_GRP, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
782 return pList.release();
786 _Font::GetFaceName(const Tizen::Base::String& filePath)
788 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
789 _FontRsrcManager::SharedFontResource out;
792 result r = mgr.GetTempFont(filePath, FONT_STYLE_PLAIN, _SYSTEM_DEFAULT_FONT_SIZE, out);
793 SysTryReturn(NID_GRP, r == E_SUCCESS, faceName, r, "[%s] Failed to get font", GetErrorMessage(r));
797 _IFont* pTempFont = out.get();
799 _IFont::Property property;
800 pTempFont->GetFontProperty(property);
801 faceName = String(property.pFamilyName);
808 _Font::GetNativeFont(void) const
810 return __pNativeFont;
817 _Font* pNativeFont = new (std::nothrow) _Font(*this);
818 SysTryReturn(NID_GRP, pNativeFont, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
825 _Font::ApplyAttribute()
827 _IFont::Attrib fontAttrib;
828 bool rtn = __pNativeFont->GetAttrib(fontAttrib);
829 SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to get font attribute");
831 fontAttrib.size = __fontAttrib.size;
832 fontAttrib.style = _IFont::STYLE_NONE;
833 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
834 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
835 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
836 fontAttrib.xExpansion = __fontAttrib.xExpansion;
837 rtn = __pNativeFont->SetAttrib(fontAttrib);
838 SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to set font attribute");
844 _Font::GetTextExtent(int width, const _Util::String& text, bool outline, int& count, Dimension& pcDim) const
846 if (text.pStart == null || text.length <= 0)
853 result r = this->__GetTextExtentEx(width, text, outline, count, pcDim);
860 _TextBidiPropertyWithReorder bidiProperty(text.pStart, text.length, _Util::Convert<TextBidiHint, _TextBidiProperty::BidiHint>(_GetTextBidiHint()));
862 if (bidiProperty.HasComplexText())
864 typedef _Util::AccumList<_Util::Pair<int, int> > GapList;
868 result r = this->__GetTextExtentList(bidiProperty, gapList);
877 int determinedCount = -1;
879 for (GapList::Iterator i = gapList.Begin(); i != gapList.End(); ++i)
881 left = (i->first < left) ? i->first : left;
882 right = (i->second > right) ? i->second : right;
884 if (determinedCount < 0 && i->first < width && i->second >= width)
886 if (i != gapList.Begin())
888 if (i - gapList.Begin() - 1 < text.length)
890 determinedCount = bidiProperty.pBidiIndex[i - gapList.Begin() - 1];
894 determinedCount = text.length;
899 determinedCount = bidiProperty.pBidiIndex[0];
904 if (right - left <= width)
906 pcDim.SetSize(right - left, __fontAttrib.size.ToInt());
909 else if (determinedCount > 0 && right - left > 0)
911 int expectedValue = width * text.length / (right - left);
912 int tolerance = _Util::Abs(expectedValue - determinedCount);
913 tolerance = (tolerance == 0) ? 2 : tolerance;
915 int tempCount = expectedValue <= determinedCount ? determinedCount + tolerance : determinedCount + (tolerance * 2);
916 tempCount = tempCount > text.length ? text.length : tempCount;
920 while (right - left > width)
922 _TextBidiPropertyWithReorder determinedBidiProperty(text.pStart, --tempCount, _Util::Convert<TextBidiHint, _TextBidiProperty::BidiHint>(_GetTextBidiHint()));
924 GapList determinedGapList;
926 result r = this->__GetTextExtentList(determinedBidiProperty, determinedGapList);
936 for (GapList::Iterator i = determinedGapList.Begin(); i != determinedGapList.End(); ++i)
938 left = (i->first < left) ? i->first : left;
939 right = (i->second > right) ? i->second : right;
943 pcDim.SetSize(right - left, __fontAttrib.size.ToInt());
956 return this->__GetTextExtent(width, text, outline, count, pcDim);
963 _Font::__GetTextExtentEx(int width, const _Util::String& text, bool outline, int& count, Dimension& pcDim) const
965 int preX1 = 0x7FFFFFFF;
966 int preY1 = 0x7FFFFFFF;
967 int preX2 = -0x7FFFFFFF;
968 int preY2 = -0x7FFFFFFF;
972 int x2 = -0x7FFFFFFF;
973 int y2 = -0x7FFFFFFF;
985 wchar_t leftChar = 0;
987 _IFont::Glyph* pFontGlyphData = 0;
989 _Font* pThis = const_cast <_Font*>(this);
991 APPLY_ATTRIBUTE(E_SYSTEM);
994 _IFont::SizeProperty sizeProperty;
995 GET_FONT_SIZE_PROPERTY(sizeProperty, E_SYSTEM);
997 if (__fontAttrib.style & FONT_STYLE_ITALIC)
999 italicSpace = (sizeProperty.ascender.ToInt() * 2) >> 4;
1003 _IFont::Property property;
1004 GET_FONT_PROPERTY(property, false);
1006 if (__fontAttrib.style & FONT_STYLE_BOLD && property.weightClass < _MEDIUM_FONT_BOLD_WEIGHT)
1008 _IFont::Attrib attr;
1009 pThis->GetAttrib(attr);
1010 boldSpace = static_cast<int>(attr.boldWeight.ToFloat() + 0.5f);
1013 const wchar_t* pText = text.pStart;
1014 int length = text.length;
1016 while (*pText && --length >= 0)
1019 FriBidiCharType type = fribidi_get_bidi_type((FriBidiChar) *pText);
1021 GUnicodeScript script = g_unichar_get_script(*pText);
1023 if (FRIBIDI_IS_LETTER(type) && FRIBIDI_IS_RTL(type))
1027 else if (script == G_UNICODE_SCRIPT_DEVANAGARI || script == G_UNICODE_SCRIPT_BENGALI)
1033 // getting proper _Font instance for the specified text
1034 _IFont* pFont = pThis->__GetFont(*pText);
1036 if (pFont != __pNativeFont)
1038 _IFont::Attrib fontAttrib;
1039 bool rtn = pFont->GetAttrib(fontAttrib);
1040 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to get font attribute");
1042 fontAttrib.size = __fontAttrib.size;
1043 fontAttrib.style = _IFont::STYLE_NONE;
1044 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
1045 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
1046 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
1047 fontAttrib.xExpansion = __fontAttrib.xExpansion;
1048 rtn = pFont->SetAttrib(fontAttrib);
1049 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to set font attribute");
1054 if (pFont->GetKerning(leftChar, *pText, xVec, yVec))
1060 if (pFont->LoadGlyph(*pText++, &pFontGlyphData))
1062 int glyphBoundX1 = curX;
1063 int glyphBoundY1 = curY - pFontGlyphData->yOffset.ToInt();
1064 int glyphBoundX2 = glyphBoundX1 +
1065 ((pFontGlyphData->image.width <= 0) ? pFontGlyphData->xAdvance.ToInt()
1066 : (pFontGlyphData->xOffset.ToInt() + pFontGlyphData->image.width));
1067 int glyphBoundY2 = glyphBoundY1 + pFontGlyphData->image.height;
1069 #ifdef SYNCHRONIZATION_2_0
1070 // adjusting x2 bounds for synchronizing fuctionality with 2.0
1071 glyphBoundX2 = glyphBoundX1 + pFontGlyphData->xAdvance.ToInt() + italicSpace + boldSpace;
1081 _ExpandBounds(glyphBoundX1, glyphBoundY1, x1, y1, x2, y2);
1082 _ExpandBounds(glyphBoundX2, glyphBoundY1, x1, y1, x2, y2);
1083 _ExpandBounds(glyphBoundX1, glyphBoundY2, x1, y1, x2, y2);
1084 _ExpandBounds(glyphBoundX2, glyphBoundY2, x1, y1, x2, y2);
1086 #ifdef SYNCHRONIZATION_2_0
1087 curX += pFontGlyphData->xAdvance.ToInt() + __fontAttrib.charSpace + italicSpace + boldSpace;
1089 curX += pFontGlyphData->xAdvance.ToInt() + __fontAttrib.charSpace + boldSpace;
1091 curY += pFontGlyphData->yAdvance.ToInt();
1093 pFont->UnloadGlyph(&pFontGlyphData);
1095 // check end condition
1096 // TODO, shkim, BIDI need to be cared
1097 if ((x2 - x1) > width)
1108 leftChar = *(pText - 1);
1112 if (characters == 0)
1114 pcDim.SetSize(0, 0);
1119 SysTryCatch(NID_GRP, preX1 <= preX2 && preY1 <= preY2, pcDim.SetSize(0, 0); count = 0, E_SYSTEM, "[E_SYSTEM] Failed to calculate text extent");
1122 pcDim.width = preX2 - preX1;
1123 #ifdef SYNCHRONIZATION_2_0
1124 pcDim.height = __fontAttrib.size.ToInt();
1126 pcDim.height = preY2 - preY1;
1127 #endif // SYNCHRONIZATION_2_0
1136 _Font::__GetTextExtent(int width, const _Util::String& text, bool outline, int& count, Dimension& pcDim) const
1138 if (text.pStart == null)
1140 pcDim.SetSize(0, 0);
1141 SysTryReturn(NID_GRP, false, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The given string is invalid.");
1144 int preX1 = 0x7FFFFFFF;
1145 int preY1 = 0x7FFFFFFF;
1146 int preX2 = -0x7FFFFFFF;
1147 int preY2 = -0x7FFFFFFF;
1149 int x1 = 0x7FFFFFFF;
1150 int y1 = 0x7FFFFFFF;
1151 int x2 = -0x7FFFFFFF;
1152 int y2 = -0x7FFFFFFF;
1158 int italicSpace = 0;
1164 wchar_t leftChar = 0;
1166 _IFont::Glyph* pFontGlyphData = 0;
1168 if (text.length == 0)
1171 pcDim.SetSize(0, 0);
1175 _Font* pThis = const_cast <_Font*>(this);
1177 APPLY_ATTRIBUTE(E_SYSTEM);
1180 _IFont::SizeProperty sizeProperty;
1181 GET_FONT_SIZE_PROPERTY(sizeProperty, E_SYSTEM);
1183 if (__fontAttrib.style & FONT_STYLE_ITALIC)
1185 italicSpace = (sizeProperty.ascender.ToInt() * 2) >> 4;
1189 _IFont::Property property;
1190 GET_FONT_PROPERTY(property, false);
1192 if (__fontAttrib.style & FONT_STYLE_BOLD && property.weightClass < _MEDIUM_FONT_BOLD_WEIGHT)
1194 _IFont::Attrib attr;
1195 pThis->GetAttrib(attr);
1196 boldSpace = static_cast<int>(attr.boldWeight.ToFloat() + 0.5f);
1199 const wchar_t* pText = text.pStart;
1200 int length = text.length;
1202 while (*pText && --length >= 0)
1204 // getting proper _Font instance for the specified text
1205 _IFont* pFont = pThis->__GetFont(*pText);
1207 if (pFont != __pNativeFont)
1209 _IFont::Attrib fontAttrib;
1210 bool rtn = pFont->GetAttrib(fontAttrib);
1211 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to get font attribute");
1213 fontAttrib.size = __fontAttrib.size;
1214 fontAttrib.style = _IFont::STYLE_NONE;
1215 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
1216 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
1217 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
1218 fontAttrib.xExpansion = __fontAttrib.xExpansion;
1219 rtn = pFont->SetAttrib(fontAttrib);
1220 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to set font attribute");
1225 if (pFont->GetKerning(leftChar, *pText, xVec, yVec))
1231 if (pFont->LoadGlyph(*pText++, &pFontGlyphData))
1233 int glyphBoundX1 = curX;
1234 int glyphBoundY1 = curY - pFontGlyphData->yOffset.ToInt();
1235 int glyphBoundX2 = glyphBoundX1 +
1236 ((pFontGlyphData->image.width <= 0) ? pFontGlyphData->xAdvance.ToInt()
1237 : (pFontGlyphData->xOffset.ToInt() + pFontGlyphData->image.width));
1238 int glyphBoundY2 = glyphBoundY1 + pFontGlyphData->image.height;
1240 #ifdef SYNCHRONIZATION_2_0
1241 // adjusting x2 bounds for synchronizing fuctionality with 2.0
1242 glyphBoundX2 = glyphBoundX1 + pFontGlyphData->xAdvance.ToInt() + italicSpace + boldSpace;
1252 _ExpandBounds(glyphBoundX1, glyphBoundY1, x1, y1, x2, y2);
1253 _ExpandBounds(glyphBoundX2, glyphBoundY1, x1, y1, x2, y2);
1254 _ExpandBounds(glyphBoundX1, glyphBoundY2, x1, y1, x2, y2);
1255 _ExpandBounds(glyphBoundX2, glyphBoundY2, x1, y1, x2, y2);
1257 #ifdef SYNCHRONIZATION_2_0
1258 curX += pFontGlyphData->xAdvance.ToInt() + __fontAttrib.charSpace + italicSpace + boldSpace;
1260 curX += pFontGlyphData->xAdvance.ToInt() + __fontAttrib.charSpace + boldSpace;
1262 curY += pFontGlyphData->yAdvance.ToInt();
1264 pFont->UnloadGlyph(&pFontGlyphData);
1266 // check end condition
1267 // TODO, shkim, BIDI need to be cared
1268 if ((x2 - x1) > width)
1279 leftChar = *(pText - 1);
1283 if (characters == 0)
1285 pcDim.SetSize(0, 0);
1290 SysTryCatch(NID_GRP, preX1 <= preX2 && preY1 <= preY2, pcDim.SetSize(0, 0); count = 0, E_SYSTEM, "[E_SYSTEM] Failed to calculate text extent");
1293 pcDim.width = preX2 - preX1;
1294 #ifdef SYNCHRONIZATION_2_0
1295 pcDim.height = __fontAttrib.size.ToInt();
1297 pcDim.height = preY2 - preY1;
1298 #endif // SYNCHRONIZATION_2_0
1307 _Font::GetTextExtent(int width, const _Util::String& text, bool outline, const Tizen::Base::String& delimiter, int& count, Dimension& dim) const
1309 const wchar_t* pText = text.pStart;
1310 const wchar_t* pTextEnd = pText + text.length;
1312 while (pText < pTextEnd)
1314 if (*pText == 0x0D || *pText == 0x0A)
1323 return this->GetTextExtent(width, _Util::String(text.pStart, pTextEnd - text.pStart), outline, count, dim);
1327 _Font::__GetTextExtentList(const _Util::String& text, _Util::AccumList<_Util::Pair<int, int> >& outList) const
1329 SysAssert(text.pStart != null && text.length > 0);
1333 _Font* pThis = const_cast <_Font*>(this);
1335 APPLY_ATTRIBUTE(E_SYSTEM);
1337 int addingSpace = __fontAttrib.charSpace;
1339 #ifdef SYNCHRONIZATION_2_0
1341 _IFont::SizeProperty sizeProperty;
1343 GET_FONT_SIZE_PROPERTY(sizeProperty, E_SYSTEM);
1345 if (__fontAttrib.style & FONT_STYLE_ITALIC)
1347 addingSpace += (sizeProperty.ascender.ToInt() * 2) >> 4;
1352 _IFont::Property property;
1353 GET_FONT_PROPERTY(property, false);
1355 if (__fontAttrib.style & FONT_STYLE_BOLD && property.weightClass < _MEDIUM_FONT_BOLD_WEIGHT)
1357 _IFont::Attrib attr;
1359 if (pThis->GetAttrib(attr))
1361 addingSpace += static_cast<int>(attr.boldWeight.ToFloat() + 0.5f);
1367 wchar_t prevChar = 0;
1369 const wchar_t* pText = text.pStart;
1370 int length = text.length;
1374 while (*(++pText) && --length >= 0)
1376 _IFont* pFont = pThis->__GetFont(*pText);
1380 if (pFont != __pNativeFont)
1382 _IFont::Attrib fontAttrib;
1384 if (pFont->GetAttrib(fontAttrib))
1386 fontAttrib.size = __fontAttrib.size;
1387 fontAttrib.style = _IFont::STYLE_NONE;
1388 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
1389 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
1390 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
1391 fontAttrib.xExpansion = __fontAttrib.xExpansion;
1392 pFont->SetAttrib(fontAttrib);
1396 _IFont::Glyph* pFontGlyphData = 0;
1398 if (pFont->LoadGlyph(*pText, &pFontGlyphData))
1400 // When LoadGlyph fails continuously in the original code, there is a problem to check the kerning on the results of the previous prevChar
1406 if (pFont->GetKerning(prevChar, *pText, xVec, yVec))
1414 curX += pFontGlyphData->xAdvance.ToInt() + addingSpace;
1415 curY += pFontGlyphData->yAdvance.ToInt();
1417 pFont->UnloadGlyph(&pFontGlyphData);
1420 outList.Push(_Util::MakePair(prevX, curX));
1426 // Cannot determine a glyph extent
1428 outList.Push(_Util::MakePair(curX, curX));
1435 _Font::__GetTextExtentList(_TextBidiPropertyWithReorder& bidiProperty, _Util::AccumList<_Util::Pair<int, int> >& outList) const
1437 if (bidiProperty.length <= 0)
1444 _Util::AccumList<_Util::Pair<int, int> > tempList;
1450 int length = bidiProperty.length;
1452 _Font* pThis = const_cast <_Font*>(this);
1454 pThis->ApplyAttribute();
1456 const wchar_t* pReorderedText = bidiProperty.GetReorderedText();
1458 const wchar_t* pTextFragmentBegin = pReorderedText;
1459 const wchar_t* pTextFragmentEnd = pTextFragmentBegin + length;
1461 const wchar_t* pTextSegment = pTextFragmentBegin;
1463 _IFont* pBaseFont = pThis->__GetFont(*pTextSegment);
1465 _Util::AccumList<_TextFragment> textFragmentList;
1467 while (pTextSegment < pTextFragmentEnd)
1469 if (pBaseFont->CheckGlyph(*pTextSegment) == 0)
1471 _IFont* pFallbackFont = pThis->__GetFont(*pTextSegment);
1473 if (pBaseFont != pFallbackFont)
1475 textFragmentList.Push(_TextFragment(_Util::String(pTextFragmentBegin, pTextSegment - pTextFragmentBegin), pBaseFont));
1477 pTextFragmentBegin = pTextSegment;
1478 pBaseFont = pFallbackFont;
1485 textFragmentList.Push(_TextFragment(_Util::String(pTextFragmentBegin, pTextSegment - pTextFragmentBegin), pBaseFont));
1489 * for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.Begin(); textFragment != textFragmentList.End(); ++textFragment)
1492 * for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.End(); textFragment != textFragmentList.Begin(); )
1498 for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.Begin(); textFragment != textFragmentList.End(); ++textFragment)
1500 if (textFragment->pUsingFont == null || textFragment->textFragment.length <= 0)
1505 if (textFragment->pUsingFont != __pNativeFont)
1507 _IFont::Attrib fontAttrib;
1509 if (textFragment->pUsingFont->GetAttrib(fontAttrib))
1511 fontAttrib.size = __fontAttrib.size;
1512 fontAttrib.style = _IFont::STYLE_NONE;
1513 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
1514 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
1515 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
1516 fontAttrib.xExpansion = __fontAttrib.xExpansion;
1517 textFragment->pUsingFont->SetAttrib(fontAttrib);
1521 Tizen::Base::Collection::ArrayListT<_IFont::Glyph *> glyphList;
1523 const wchar_t firstChar = *textFragment->textFragment.pStart;
1525 GUnicodeScript script = _TextBidiUtil::GetUnicodeScript(firstChar);
1526 // need to check if (script < 0 || script >= _sampleLanguageCount) ?
1528 textFragment->pUsingFont->GetGlyphList(textFragment->textFragment, glyphList, script);
1530 int count = glyphList.GetCount();
1532 for (int i = 0; i < count; i++)
1534 _IFont::Glyph *pGlyph = 0;
1536 glyphList.GetAt(i, pGlyph);
1538 // bug fixed in test case of L"\x9a8\x20\x981\x9a0\x635"
1539 //if (pGlyph->xAdvance == 0 && pGlyph->image.width == 0)
1546 xDest += pGlyph->xAdvance.ToInt();
1547 yDest += pGlyph->yAdvance.ToInt();
1549 tempList.Push(_Util::MakePair(prevX, xDest));
1550 outList.Push(_Util::MakePair(-1, -1));
1553 IEnumeratorT<_IFont::Glyph*>* pEnum = glyphList.GetEnumeratorN();
1557 while (pEnum->MoveNext() == E_SUCCESS)
1559 _IFont::Glyph* pGlyph;
1561 pEnum->GetCurrent(pGlyph);
1562 pBaseFont->UnloadGlyph(&pGlyph);
1570 if (bidiProperty.pBidiIndex)
1572 // Reorder list by using BIDI index
1573 typedef _Util::Pair<int, int> Gap;
1574 typedef _Util::AccumList<Gap> GapList;
1576 GapList::Iterator dstBegin = outList.Begin();
1580 if (bidiProperty.length == int(tempList.Size()))
1582 for (GapList::ConstIterator src = tempList.Begin(); src != tempList.End(); ++src)
1584 *(dstBegin + bidiProperty.pBidiIndex[index++]) = *src;
1587 else if (bidiProperty.length > int(tempList.Size()))
1589 _TextBidiUtil::GetReorderedIndexList(bidiProperty, tempList, outList);
1591 else // if (bidiProperty.length < tempList.Size())
1593 // under development
1594 for (GapList::ConstIterator src = tempList.Begin(); src != tempList.End() && index < bidiProperty.length; ++src)
1596 *(dstBegin + bidiProperty.pBidiIndex[index++]) = *src;
1602 typedef _Util::Pair<int, int> Gap;
1603 typedef _Util::AccumList<Gap> GapList;
1605 GapList::Iterator dst = outList.Begin();
1606 GapList::Iterator dstEnd = outList.End();
1608 GapList::ConstIterator src = tempList.Begin();
1609 GapList::ConstIterator srcEnd = tempList.End();
1611 for (; (src != srcEnd) && (dst != dstEnd); ++src, ++dst)
1621 _Font::GetTextExtentList(const _Util::String& text, _Util::AccumList<_Util::Pair<int, int> >& outList) const
1623 if (text.pStart == null || text.length <= 0)
1629 _TextBidiPropertyWithReorder bidiProperty(text.pStart, text.length, _Util::Convert<TextBidiHint, _TextBidiProperty::BidiHint>(_GetTextBidiHint()));
1631 if (bidiProperty.HasComplexText())
1633 return this->__GetTextExtentList(bidiProperty, outList);
1637 return this->__GetTextExtentList(text, outList);
1644 _Font::SetSize(_Util::FixedPoint26_6 pcSize)
1646 __UpdateFontAttribute(__fontAttrib.style, pcSize);
1652 _Font::SetStyle(int style)
1654 __fontAttrib.style = style;
1660 _Font::GetStyle(void) const
1662 return __fontAttrib.style;
1665 _Util::FixedPoint26_6
1666 _Font::GetLeading(void) const
1669 return __fontAttrib.maxHeight;
1671 return __fontAttrib.ascender - __fontAttrib.descender + __fontAttrib.leading;
1676 _Font::__DrawText(_Canvas& canvas, const Point& point, const _Util::String& text, unsigned long color, bool ignorePredefinedColor)
1678 SysTryReturnResult(NID_GRP, canvas.__pScratchPad != null, E_INVALID_ARG, "A canvas is invalid");
1680 bool rtn = this->ApplyAttribute();
1681 SysTryReturn(NID_GRP, rtn, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fails to apply font attribute.");
1683 _Util::ScratchPad <SystemPixel>& scratchPad = *canvas.__pScratchPad;
1684 scratchPad.RegisterFillRect(_RasterOp::FnFillRectFont32Bit);
1686 Rectangle clipBounds;
1687 canvas.__GetClipBounds(clipBounds);
1689 int xDest = point.x;
1690 int yDest = point.y;
1691 int startX = point.x;
1693 int italicSpace = 0;
1695 int clipX1 = clipBounds.x;
1696 int clipY1 = clipBounds.y;
1697 int clipX2 = clipX1 + clipBounds.width;
1698 int clipY2 = clipY1 + clipBounds.height;
1702 wchar_t leftChar = 0;
1703 _IFont::Glyph* pFontGlyphData = 0;
1705 _IFont::SizeProperty sizeProperty;
1706 rtn = this->GetFontSizeProperty(sizeProperty);
1707 SysTryReturn(NID_GRP, rtn, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to get font sizeProperty.");
1709 // need to revise y value, because _IFont is based on the baseline
1711 if (canvas.__textOrigin == TEXT_ORIGIN_LEFT_TOP)
1713 yDest += sizeProperty.ascender.ToInt();
1716 charHeight = sizeProperty.ascender.ToInt() - sizeProperty.descender.ToInt();
1718 if (this->GetStyle() & FONT_STYLE_ITALIC)
1720 italicSpace = (sizeProperty.ascender.ToInt() * 2) >> 4;
1724 _IFont::Property property;
1725 GET_FONT_PROPERTY(property, false);
1727 if (__fontAttrib.style & FONT_STYLE_BOLD && property.weightClass < _MEDIUM_FONT_BOLD_WEIGHT)
1729 _IFont::Attrib attr;
1730 this->GetAttrib(attr);
1731 boldSpace = static_cast<int>(attr.boldWeight.ToFloat() + 0.5f);
1734 const wchar_t* pText = text.pStart;
1735 int length = text.length;
1737 unsigned long canvasFgColor = color;
1739 _TextBidiPropertyWithReorder bidiProperty(pText, length, _Util::Convert<TextBidiHint, _TextBidiProperty::BidiHint>(_GetTextBidiHint()));
1741 if (bidiProperty.HasComplexText())
1743 const wchar_t* pReorderedText = bidiProperty.GetReorderedText();
1745 const wchar_t* pTextFragmentBegin = pReorderedText;
1746 const wchar_t* pTextFragmentEnd = pTextFragmentBegin + length;
1748 const wchar_t* pTextSegment = pTextFragmentBegin;
1750 _IFont* pBaseFont = this->__GetFont(*pTextSegment);
1752 _Util::AccumList<_TextFragment> textFragmentList;
1754 while (pTextSegment < pTextFragmentEnd)
1756 if (pBaseFont->CheckGlyph(*pTextSegment) == 0)
1758 _IFont* pFallbackFont = this->__GetFont(*pTextSegment);
1760 if (pBaseFont != pFallbackFont)
1762 textFragmentList.Push(_TextFragment(_Util::String(pTextFragmentBegin, pTextSegment - pTextFragmentBegin), pBaseFont));
1764 pTextFragmentBegin = pTextSegment;
1765 pBaseFont = pFallbackFont;
1772 textFragmentList.Push(_TextFragment(_Util::String(pTextFragmentBegin, pTextSegment - pTextFragmentBegin), pBaseFont));
1776 * for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.Begin(); textFragment != textFragmentList.End(); ++textFragment)
1779 * for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.End(); textFragment != textFragmentList.Begin(); )
1785 for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.Begin(); textFragment != textFragmentList.End(); ++textFragment)
1787 if (textFragment->pUsingFont == null || textFragment->textFragment.length <= 0)
1792 if (textFragment->pUsingFont != __pNativeFont)
1794 _IFont::Attrib fontAttrib;
1796 if (textFragment->pUsingFont->GetAttrib(fontAttrib))
1798 fontAttrib.size = __fontAttrib.size;
1799 fontAttrib.style = _IFont::STYLE_NONE;
1800 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
1801 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
1802 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
1803 fontAttrib.xExpansion = __fontAttrib.xExpansion;
1804 textFragment->pUsingFont->SetAttrib(fontAttrib);
1808 Tizen::Base::Collection::ArrayListT<_IFont::Glyph *> glyphList;
1810 const wchar_t firstChar = *textFragment->textFragment.pStart;
1812 GUnicodeScript script = _TextBidiUtil::GetUnicodeScript(firstChar);
1814 textFragment->pUsingFont->GetGlyphList(textFragment->textFragment, glyphList, script);
1815 // need to check if (script < 0 || script >= _sampleLanguageCount) ?
1817 int count = glyphList.GetCount();
1819 for (int i = 0; i < count; i++)
1822 static int s_index = 0;
1823 const unsigned long COLOR[6] =
1832 unsigned long canvasFgColor = COLOR[s_index++ % 6];
1835 typedef unsigned long TPixel;
1836 _IFont::Glyph *pGlyph = 0;
1838 TPixel srcR, srcG, srcB, srcA;
1839 TPixel dstR, dstG, dstB, dstA;
1841 srcA = (canvasFgColor >> 24) & 0xFF;
1842 srcA += (srcA >> 7);
1843 srcR = (canvasFgColor >> 16) & 0xFF;
1844 srcG = (canvasFgColor >> 8) & 0xFF;
1845 srcB = (canvasFgColor) & 0xFF;
1847 SystemPixel* pBufferStartAddr = null;
1850 scratchPad.GetBuffer(pBufferStartAddr, bufferPitch);
1852 glyphList.GetAt(i, pGlyph);
1854 if (!_TextBidiUtil::IsTextBidiBaseLtr())
1856 xDest -= pGlyph->xAdvance.ToInt();
1857 yDest -= pGlyph->yAdvance.ToInt();
1860 // temporary indent for convenience of code review
1861 switch (pGlyph->image.depth)
1865 for (int h = 0; h < pGlyph->image.height; h++)
1867 int y = yDest - pGlyph->yOffset.ToInt() + h;
1879 TPixel* pDest32 = pBufferStartAddr + y * bufferPitch + xDest + pGlyph->xOffset.ToInt();
1881 for (int w = 0; w < pGlyph->image.width; w++)
1883 int x = xDest + pGlyph->xOffset.ToInt() + w;
1896 unsigned long alpha = (unsigned long) (pGlyph->image.pBitmap[h * pGlyph->image.bytesPerLine + w]);
1900 // equivalent to scratchPad.FillRect(x, y, 1, 1, fgColor, alpha);
1901 alpha = (alpha * srcA) >> 8;
1902 alpha += (alpha >> 7);
1904 dstA = (*pDest32 >> 24) & 0xFF;
1905 dstR = (*pDest32 >> 16) & 0xFF;
1906 dstG = (*pDest32 >> 8) & 0xFF;
1907 dstB = (*pDest32) & 0xFF;
1909 dstA = BLEND_ALPHA_COMPONEMT(alpha, dstA);
1910 dstR = (dstR + (((srcR - dstR) * alpha) >> 8)) & 0xFF;
1911 dstG = (dstG + (((srcG - dstG) * alpha) >> 8)) & 0xFF;
1912 dstB = (dstB + (((srcB - dstB) * alpha) >> 8)) & 0xFF;
1914 *pDest32 = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB;
1925 scratchPad.RegisterFillRect(_RasterOp::FnFillRectAlpha32Bit);
1927 for (int h = 0; h < pGlyph->image.height; h++)
1929 int y = yDest - pGlyph->yOffset.ToInt() + h;
1941 TPixel* pDest32 = pBufferStartAddr + y * bufferPitch + xDest + pGlyph->xOffset.ToInt();
1943 for (int w = 0; w < pGlyph->image.width; w++)
1945 int x = xDest + pGlyph->xOffset.ToInt() + w;
1958 unsigned long* pSource = (unsigned long*)&pGlyph->image.pBitmap[h * pGlyph->image.bytesPerLine];
1961 scratchPad.FillRect(x, y, 1, 1, *pSource, 255);
1965 scratchPad.RegisterFillRect(_RasterOp::FnFillRectFont32Bit);
1971 if (_TextBidiUtil::IsTextBidiBaseLtr())
1973 xDest += pGlyph->xAdvance.ToInt();
1974 yDest += pGlyph->yAdvance.ToInt();
1978 IEnumeratorT<_IFont::Glyph*>* pEnum = glyphList.GetEnumeratorN();
1982 while (pEnum->MoveNext() == E_SUCCESS)
1984 _IFont::Glyph* pGlyph;
1986 pEnum->GetCurrent(pGlyph);
1987 pBaseFont->UnloadGlyph(&pGlyph);
1996 while (*pText && --length >= 0)
1998 // find out proper native font
1999 _IFont* pFont = this->__GetFont(*pText);
2006 if (pFont != __pNativeFont)
2008 _IFont::Attrib fontAttrib;
2009 bool rtn = pFont->GetAttrib(fontAttrib);
2010 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to get font attribute");
2012 fontAttrib.size = __fontAttrib.size;
2013 fontAttrib.style = _IFont::STYLE_NONE;
2014 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
2015 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
2016 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
2017 fontAttrib.xExpansion = __fontAttrib.xExpansion;
2018 rtn = pFont->SetAttrib(fontAttrib);
2019 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to set font attribute");
2022 _IFont::Property property;
2023 pFont->GetFontProperty(property);
2025 unsigned long fgColor = (!ignorePredefinedColor && pFont->hasPredefinedColor()) ? _GetPredefinedColor(*pText, canvasFgColor) : canvasFgColor;
2029 if (pFont->GetKerning(leftChar, *pText, xVec, yVec))
2035 bool rtn = pFont->LoadGlyph(*pText++, &pFontGlyphData);
2042 typedef unsigned long TPixel;
2044 // temporary indent for convenience of code review
2045 switch (pFontGlyphData->image.depth)
2049 TPixel srcA = (fgColor >> 24) & 0xFF;
2050 srcA += (srcA >> 7);
2052 TPixel srcR = (fgColor >> 16) & 0xFF;
2053 TPixel srcG = (fgColor >> 8) & 0xFF;
2054 TPixel srcB = (fgColor) & 0xFF;
2056 SystemPixel* pBufferStartAddr = null;
2057 int bufferPitch = 0;
2059 scratchPad.GetBuffer(pBufferStartAddr, bufferPitch);
2061 for (int h = 0; h < pFontGlyphData->image.height; h++)
2063 int y = yDest - pFontGlyphData->yOffset.ToInt() + h;
2075 TPixel* pDest32 = pBufferStartAddr + y * bufferPitch + xDest + pFontGlyphData->xOffset.ToInt();
2077 for (int w = 0; w < pFontGlyphData->image.width; w++)
2079 int x = xDest + pFontGlyphData->xOffset.ToInt() + w;
2092 unsigned long alpha = (unsigned long) (pFontGlyphData->image.pBitmap[h * pFontGlyphData->image.bytesPerLine + w]);
2096 // equivalent to scratchPad.FillRect(x, y, 1, 1, fgColor, alpha);
2097 alpha = (alpha * srcA) >> 8;
2098 alpha += (alpha >> 7);
2100 TPixel dstA = (*pDest32 >> 24) & 0xFF;
2101 TPixel dstR = (*pDest32 >> 16) & 0xFF;
2102 TPixel dstG = (*pDest32 >> 8) & 0xFF;
2103 TPixel dstB = (*pDest32) & 0xFF;
2105 dstA = BLEND_ALPHA_COMPONEMT(alpha, dstA);
2106 dstR = (dstR + (((srcR - dstR) * alpha) >> 8)) & 0xFF;
2107 dstG = (dstG + (((srcG - dstG) * alpha) >> 8)) & 0xFF;
2108 dstB = (dstB + (((srcB - dstB) * alpha) >> 8)) & 0xFF;
2110 *pDest32 = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB;
2117 xDest += pFontGlyphData->xAdvance.ToInt() + __fontAttrib.charSpace + italicSpace + boldSpace;
2118 yDest += pFontGlyphData->yAdvance.ToInt();
2120 leftChar = *(pText - 1);
2122 pFont->UnloadGlyph(&pFontGlyphData);
2128 scratchPad.RegisterFillRect(_RasterOp::FnFillRectAlpha32Bit);
2130 for (int h = 0; h < pFontGlyphData->image.height; h++)
2132 int y = yDest - pFontGlyphData->yOffset.ToInt() + h;
2144 for (int w = 0; w < pFontGlyphData->image.width; w++)
2146 int x = xDest + pFontGlyphData->xOffset.ToInt() + w;
2158 unsigned long* pSource = (unsigned long*)&pFontGlyphData->image.pBitmap[h * pFontGlyphData->image.bytesPerLine];
2161 scratchPad.FillRect(x, y, 1, 1, *pSource, 255);
2165 xDest += pFontGlyphData->xAdvance.ToInt() + __fontAttrib.charSpace + italicSpace + boldSpace;
2166 yDest += pFontGlyphData->yAdvance.ToInt();
2168 leftChar = *(pText - 1);
2170 pFont->UnloadGlyph(&pFontGlyphData);
2172 scratchPad.RegisterFillRect(_RasterOp::FnFillRectFont32Bit);
2180 if (this->IsUnderlined() || this->IsStrikeOut())
2183 int thick = this->GetLineThickness();
2185 if (canvas.__textOrigin == TEXT_ORIGIN_LEFT_TOP)
2187 y = point.y + charHeight - 1;
2191 y = point.y - sizeProperty.descender.ToInt() - 1;
2194 xDest -= this->GetCharSpace();
2196 if (this->IsUnderlined())
2198 canvas.FillRectangle(canvasFgColor, Rectangle(startX, y - thick, xDest - startX, thick));
2201 if (this->IsStrikeOut())
2203 y -= charHeight / 2;
2204 canvas.FillRectangle(canvasFgColor, Rectangle(startX, y - thick, xDest - startX, thick));
2208 scratchPad.RegisterFillRect(null);
2213 #undef BLEND_ALPHA_COMPONEMT
2216 _Font::__DrawText(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length)
2218 _Util::String utilText(text.GetPointer(), text.GetLength(), startIndex, length);
2220 return this->__DrawText(canvas, point, utilText, canvas.__fgColor, false);
2224 _Font::__DrawText(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length, const Color& outlineColor)
2226 unsigned long textColor32 = canvas.__fgColor;
2227 unsigned long outlineColor32 = outlineColor.GetRGB32();;
2229 _Util::String utilText(text.GetPointer(), text.GetLength(), startIndex, length);
2231 this->__DrawText(canvas, Point(point.x - 1, point.y), utilText, outlineColor32, true);
2232 this->__DrawText(canvas, Point(point.x + 1, point.y), utilText, outlineColor32, true);
2233 this->__DrawText(canvas, Point(point.x, point.y - 1), utilText, outlineColor32, true);
2234 this->__DrawText(canvas, Point(point.x, point.y + 1), utilText, outlineColor32, true);
2236 this->__DrawText(canvas, point, utilText, textColor32, false);
2242 _Font::SetAttrib(const _IFont::Attrib& fontAttrib)
2244 return __pNativeFont->SetAttrib(fontAttrib);
2248 _Font::GetAttrib(_IFont::Attrib& fontAttrib) const
2250 return __pNativeFont->GetAttrib(fontAttrib);
2254 _Font::GetKerning(unsigned long character1, unsigned long character2, long& xVector, long& yVector) const
2256 return __pNativeFont->GetKerning(character1, character2, xVector, yVector);
2260 _Font::GetFontSizeProperty(_IFont::SizeProperty& sizeProperty) const
2262 return __pNativeFont->GetFontSizeProperty(sizeProperty);
2266 _Font::LoadGlyph(unsigned long character, _IFont::Glyph** ppFontGlyphData)
2268 // note! we assume that the font attribute has been already applied on _IFont
2271 // if not, loading glyph (character/size/style) and caching it
2272 rtn = __pNativeFont->LoadGlyph(character, ppFontGlyphData);
2273 SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to load glyph data");
2275 // return cached glyph
2280 _Font::UnloadGlyph(_IFont::Glyph** ppFontGlyphData)
2282 return __pNativeFont->UnloadGlyph(ppFontGlyphData);
2286 _Font::CheckGlyph(unsigned long character)
2288 return __pNativeFont->CheckGlyph(character);
2292 _Font::GetFontSizeFromMaxHeight(const _Util::FixedPoint26_6 expectedMaxHeight)
2294 return __pNativeFont->GetFontSizeFromMaxHeight(expectedMaxHeight);
2298 _Font::GetFontSizeFromMaxHeight(int style, const _Util::FixedPoint26_6 expectedMaxHeight)
2300 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
2301 _FontRsrcManager::SharedFontResource out;
2303 result r = mgr.GetFont(style, expectedMaxHeight, out);
2304 SysTryReturn(NID_GRP, r == E_SUCCESS, -1.0f, r, "[%s] Getting system default font failed.", GetErrorMessage(r));
2306 _IFont* pTempFont = out.get();
2308 return pTempFont->GetFontSizeFromMaxHeight(expectedMaxHeight);
2312 _Font::GetFontSizeFromMaxHeight(const Tizen::Base::String& fontName, int style, const _Util::FixedPoint26_6 expectedMaxHeight)
2314 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
2315 _FontRsrcManager::SharedFontResource out;
2317 result r = mgr.GetFont(fontName, style, expectedMaxHeight, out);
2318 SysTryReturn(NID_GRP, r == E_SUCCESS, -1.0f, r, "[%s] Getting font failed.", GetErrorMessage(r));
2320 _IFont* pTempFont = out.get();
2322 return pTempFont->GetFontSizeFromMaxHeight(expectedMaxHeight);
2326 _Font::__UpdateFontAttribute(int style, _Util::FixedPoint26_6 pcSize)
2328 __fontAttrib.style = style;
2329 __fontAttrib.size = pcSize;
2330 __fontAttrib.lineThickness = pcSize.ToInt() > 0 ? (pcSize.ToInt() / 24) + 1 : 1;
2332 _IFont::SizeProperty sizeProperty;
2333 bool getProperty = false;
2335 if (this->ApplyAttribute())
2337 getProperty = __pNativeFont->GetFontSizeProperty(sizeProperty);
2342 __fontAttrib.maxWidth = sizeProperty.maxWidth;
2343 __fontAttrib.maxHeight = sizeProperty.maxHeight;
2344 __fontAttrib.ascender = sizeProperty.ascender;
2345 __fontAttrib.descender = sizeProperty.descender;
2346 __fontAttrib.leading = sizeProperty.leading;
2350 // if failed to get property above, each property should be remained as default: -1
2351 SysLog(NID_GRP, "[] Failed to get font attribute from native font");
2353 __fontAttrib.maxWidth.Reset(0);
2354 __fontAttrib.maxHeight.Reset(0);
2355 __fontAttrib.ascender.Reset(0);
2356 __fontAttrib.descender.Reset(0);
2357 __fontAttrib.leading.Reset(0);
2362 _Font::__DrawTextLastFallback(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length)
2368 _Font::__DrawTextDefault(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length)
2370 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
2371 result r = mgr.GetDefaultSystemFont().__DrawText(canvas, point, text, startIndex, length);
2372 SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Failed to draw default system font", GetErrorMessage(r));
2377 _Font::__DrawTextLastFallback(canvas, point, text, startIndex, length);
2382 _Font::__DrawTextDefault(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length, const Color& outlineColor)
2384 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
2385 result r = mgr.GetDefaultSystemFont().__DrawText(canvas, point, text, startIndex, length, outlineColor);
2386 SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Failed to draw default system font", GetErrorMessage(r));
2391 _Font::__DrawTextLastFallback(canvas, point, text, startIndex, length);
2397 _Font::DrawText(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length)
2399 if (canvas.__pPriorityFont)
2401 return canvas.__pPriorityFont->__DrawText(canvas, point, text, startIndex, length);
2403 else if (canvas.__pFont)
2405 return canvas.__pFont->__DrawText(canvas, point, text, startIndex, length);
2409 return _Font::__DrawTextDefault(canvas, point, text, startIndex, length);
2414 _Font::DrawText(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length, const Color& outlineColor)
2416 if (canvas.__pPriorityFont)
2418 return canvas.__pPriorityFont->__DrawText(canvas, point, text, startIndex, length, outlineColor);
2420 else if (canvas.__pFont)
2422 return canvas.__pFont->__DrawText(canvas, point, text, startIndex, length, outlineColor);
2426 return _Font::__DrawTextDefault(canvas, point, text, startIndex, length, outlineColor);
2433 _Font::GetInstance(_FontImpl& font)
2435 return (&font != null) ? font._pNativeFont : null;
2439 _Font::GetInstance(const _FontImpl& font)
2441 return (&font != null) ? font._pNativeFont : null;
2445 _Font::__GetFont(wchar_t character)
2447 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
2449 //------------------------------------------------------
2451 // 1. check if this font has a requested glyph
2453 //------------------------------------------------------
2454 unsigned long idx = __pNativeFont->CheckGlyph(character);
2458 return __pNativeFont;
2461 // Check the BlackList
2462 if (mgr.SearchBlackList(character))
2464 return __pNativeFont;
2467 //------------------------------------------------------
2469 // 1-2. check if this glyph is in the fallback list.
2471 //------------------------------------------------------
2472 _IFont::FontMapT* pFallbackFontMap = __pNativeFont->GetFallbackMap();
2474 #ifdef USE_HASHMAP_FOR_FONT
2475 std::auto_ptr<IMapEnumeratorT<_Util::WString, _FontRsrcManager::SharedFontResource> > enumerator(pFallbackFontMap->GetMapEnumeratorN());
2477 while (enumerator->MoveNext() == E_SUCCESS)
2479 _FontRsrcManager::SharedFontResource pTempFont;
2481 if (enumerator->GetValue(pTempFont) == E_SUCCESS)
2483 _Util::WString key(L"");
2484 result r = enumerator->GetKey(key);
2488 if (mgr.SearchFont(key))
2490 if (pTempFont.get()->CheckGlyph(character) > 0)
2492 return pTempFont.get();
2497 pFallbackFontMap->Remove(key);
2503 for (_IFont::FontMapT::const_iterator fontIterator = pFallbackFontMap->begin(); fontIterator != pFallbackFontMap->end(); ++fontIterator)
2505 if (fontIterator->second != null)
2507 if (fontIterator->second->CheckGlyph(character) > 0)
2509 return fontIterator->second.get();
2515 //------------------------------------------------------
2517 // 2. Get fallback font list via fontconfig
2519 //------------------------------------------------------
2520 Tizen::Base::Collection::ArrayListT<String> fileList;
2521 bool rtn = __GetFallbackFontFileList(character, fileList);
2525 // if failed find out fallback font,
2526 // just use this instance for drawing something for unknown glyph
2527 return __pNativeFont;
2530 //------------------------------------------------------
2532 // 3. try to find a font having a requested glyph
2534 //------------------------------------------------------
2536 _IFont* pFallbackFont = null;
2538 _FontRsrcManager::SharedFontResource out;
2540 int count = fileList.GetCount();
2541 result r = E_FAILURE;
2543 for (int i = 0; i < count; i++)
2545 fileList.GetAt(i, fontName);
2547 if (fontName.IsEmpty())
2552 r = mgr.GetTempFont(fontName, __fontAttrib.style, __fontAttrib.size, out);
2556 unsigned long idx = out->CheckGlyph(character);
2560 _Util::WString fontNameTemp(fontName.GetPointer());
2563 #ifdef USE_HASHMAP_FOR_FONT
2564 r = pFallbackFontMap->Add(fontNameTemp, out);
2566 if (r == E_OBJ_ALREADY_EXIST)
2568 pFallbackFont = out.get();
2572 SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
2574 pFallbackFontMap->push_back(std::make_pair(fontNameTemp, out));
2576 r = mgr.AddFont(fontNameTemp, out);
2577 SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
2579 pFallbackFont = out.get();
2585 if (pFallbackFont == null)
2587 mgr.AddBlackList(character);
2589 return __pNativeFont;
2592 return pFallbackFont;
2595 // if failed find out fallback font,
2596 // just use this instance for drawing something for unknown glyph
2597 return __pNativeFont;
2601 _Font::__GetFallbackFontFileList(wchar_t character, Tizen::Base::Collection::IListT<String>& out)
2603 GUnicodeScript script = g_unichar_get_script(character);
2604 if (script < 0 || script >= _sampleLanguageCount)
2609 FcPattern* pPattern = null;
2610 FcFontSet* pSet = null;
2611 FcChar8* pName = null;
2612 FcResult res = FcResultNoMatch;
2613 const int fcWeight = (__fontAttrib.style & FONT_STYLE_BOLD) ? FC_WEIGHT_BOLD : FC_WEIGHT_REGULAR;
2615 // getting fallback font list
2616 pPattern = FcPatternBuild(NULL, FC_WEIGHT, FcTypeInteger, fcWeight, NULL);
2617 SysTryCatch(NID_GRP, pPattern, , E_SYSTEM, "[E_SYSTEM] Failed to FcPatternBuild()");
2619 FcPatternAddString(pPattern, FC_FAMILY, (FcChar8*)"Tizen");
2621 if (strncmp(SAMPLE_LANGUAGE_EMPTY, _SampleLanguages[script], strlen(SAMPLE_LANGUAGE_EMPTY) + 1) != 0)
2623 FcPatternAddString(pPattern, FC_LANG, (FcChar8*)_SampleLanguages[script]);
2626 FcConfigSubstitute(NULL, pPattern, FcMatchPattern);
2627 FcDefaultSubstitute(pPattern);
2630 pSet = FcFontSort(NULL, pPattern, FcTrue, NULL, &res);
2631 SysTryCatch(NID_GRP, pSet, , E_SYSTEM, "[E_SYSTEM] Failed to FcFontSort()");
2635 for (int i = 0; i < pSet->nfont; i++)
2637 if (FcPatternGetString(pSet->fonts[i], FC_FILE, 0, &pName) == FcResultMatch)
2639 out.Add(String((char*)pName));
2644 FcFontSetDestroy(pSet);
2645 FcPatternDestroy(pPattern);
2647 return (out.GetCount() > 0) ? true : false;
2651 FcFontSetDestroy(pSet);
2654 if (pPattern != null)
2656 FcPatternDestroy(pPattern);
2663 _Font::UpdateDefaultFont(const String& key)
2667 SysLog(NID_GRP, "Request to change the default font");
2669 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
2671 return mgr.ReloadDefaultSystemFont();
2677 }} // Tizen::Graphics