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 APPLY_BOLD_SPACE
61 #define SYNCHRONIZATION_2_0
62 #define __pNativeFont __sharedFont.get()
64 #define GET_FONT_SIZE_PROPERTY(sizeProperty, rtnValue) \
66 bool rtn = __pNativeFont->GetFontSizeProperty(sizeProperty); \
67 SysTryReturn(NID_GRP, rtn, rtnValue, E_SYSTEM, "[E_SYSTEM] Failed to get font size property"); \
69 #define GET_FONT_PROPERTY(property, rtnValue) \
71 bool rtn = __pNativeFont->GetFontProperty(property); \
72 SysTryReturn(NID_GRP, rtn, rtnValue, E_SYSTEM, "[E_SYSTEM] Failed to get font property"); \
74 #define LOAD_GLYPH_DATA_CONST(character, pFontGlyphData, rtnValue) \
76 _Font* pThis = const_cast <_Font*>(this); \
77 bool rtn = pThis->LoadGlyph(character, &pFontGlyphData); \
78 SysTryReturn(NID_GRP, rtn, rtnValue, E_SYSTEM, "[E_SYSTEM] Failed to load glyph data"); \
80 #define UNLOAD_GLYPH_DATA_CONST(pFontGlyphData) \
82 _Font* pThis = const_cast <_Font*>(this); \
83 pThis->UnloadGlyph(&pFontGlyphData); \
85 #define APPLY_ATTRIBUTE(rtnValue) \
87 _Font* pFont = const_cast <_Font*>(this); \
88 bool rtn = pFont->ApplyAttribute(); \
89 SysTryReturn(NID_GRP, rtn, rtnValue, E_SYSTEM, "[E_SYSTEM] Failed to apply font attribute"); \
91 #define SAMPLE_LANGUAGE_EMPTY ""
94 using namespace Tizen::Base;
95 using namespace Tizen::Base::Collection;
96 using namespace Tizen::Base::Utility;
97 using namespace Tizen::Graphics;
98 using namespace Tizen::Io;
99 using namespace Tizen::System;
104 const _Util::FixedPoint26_6 _SYSTEM_DEFAULT_FONT_SIZE(16);
105 const long _MEDIUM_FONT_BOLD_WEIGHT = 600;
107 template<typename Type>
109 _ExpandBounds(Type curX, Type curY, Type& x1, Type& y1, Type& x2, Type& y2)
133 _GetSystemFontList(Tizen::Base::Collection::IList& list)
135 #ifdef USE_FONTCONFIG
136 FcPattern* pPattern = null;
137 FcFontSet* pSet = null;
138 FcObjectSet* pObjectSet = null;
139 const char* pLang = null;
140 const char* fcStyle = "Regular";
142 pPattern = FcPatternCreate();
143 SysTryCatch(NID_GRP, pPattern, , E_SYSTEM, "[E_SYSTEM] Failed to FcPatternCreate()");
145 // language and style
146 FcPatternAddString(pPattern, FC_STYLE, (FcChar8*)fcStyle);
148 // RFC3066 formatted 2-level language identifier will be returned.
149 // e.g., en-NR, ar-SD, byn, tig etc.
150 // but, fontconfig only need 1-level language identifier having maximum 3 letters.
151 pLang = uloc_getDefault();
155 char lang3Letters[4] = {0,};
156 strncpy(lang3Letters, pLang, 3);
158 for (int i = 0; i < 3; i++)
160 if (lang3Letters[i] == '-' || lang3Letters[i] == '_')
167 FcPatternAddString(pPattern, FC_LANG, (FcChar8*)lang3Letters);
170 pObjectSet = FcObjectSetBuild(FC_FAMILY, FC_STYLE, FC_FILE, NULL);
171 SysTryCatch(NID_GRP, pObjectSet, , E_SYSTEM, "[E_SYSTEM] Failed to FcObjectSetBuild()");
173 pSet = FcFontList(NULL, pPattern, pObjectSet);
174 SysTryCatch(NID_GRP, pSet, , E_SYSTEM, "[E_SYSTEM] Failed to init fontconfig");
177 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
178 String defaultFontFaceName(mgr.GetDefaultSystemFont().GetFaceName());
180 bool defaultFontExists = false;
182 list.RemoveAll(true);
183 FcChar8* pName = null;
185 for (int i = 0; i < pSet->nfont; i++)
187 if (FcPatternGetString(pSet->fonts[i], FC_FILE, 0, &pName) == FcResultMatch)
189 String* pFamilyName = new (std::nothrow) String(Tizen::Graphics::_Font::GetFaceName(String((char*)pName)));
190 SysTryCatch(NID_GRP, pFamilyName, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
192 list.Add(*pFamilyName);
194 if (*pFamilyName == defaultFontFaceName)
196 defaultFontExists = true;
201 if (defaultFontExists == false)
203 String* pDefaultFontName = new (std::nothrow) String(defaultFontFaceName);
204 SysTryCatch(NID_GRP, pDefaultFontName, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
206 list.InsertAt(*pDefaultFontName, 0);
211 FcFontSetDestroy(pSet);
212 FcObjectSetDestroy(pObjectSet);
213 FcPatternDestroy(pPattern);
218 list.RemoveAll(true);
220 // destroy, but before doing that check if those value has been created or not.
223 FcFontSetDestroy(pSet);
228 FcObjectSetDestroy(pObjectSet);
233 FcPatternDestroy(pPattern);
236 return GetLastResult();
239 const String FONT_DIR_PATH[] =
241 // L"/usr/share/fallback_fonts",
245 list.RemoveAll(true);
247 const int FONT_DIR_PATH_COUNT = sizeof(FONT_DIR_PATH) / sizeof(FONT_DIR_PATH[0]);
249 for (int i = 0; i < FONT_DIR_PATH_COUNT; i++)
253 result r = directory.Construct(FONT_DIR_PATH[i]);
257 std::auto_ptr<DirEnumerator> dirEnumerator(directory.ReadN());
259 while (dirEnumerator->MoveNext() == E_SUCCESS)
261 DirEntry entry = dirEnumerator->GetCurrentDirEntry();
263 if (entry.IsDirectory() == false && entry.IsHidden() == false)
265 Tizen::Base::Utility::StringTokenizer formatTok(entry.GetName(), ".");
268 while (formatTok.GetTokenCount())
270 formatTok.GetNextToken(token);
273 if (token.Equals("ttf",false) || token.Equals("ttc",false))
276 fullName.Append(FONT_DIR_PATH[i]);
277 fullName.Append(L"/");
278 fullName.Append(entry.GetName());
280 bool isNewFont = true;
282 String* pFamilyName = new (std::nothrow) String(Tizen::Graphics::_Font::GetFaceName(fullName));
283 SysTryCatch(NID_GRP, pFamilyName, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
285 for (int idx = 0; idx < list.GetCount(); idx++)
287 String* pName = static_cast <String*>(list.GetAt(idx));
294 if (*pName == *pFamilyName)
303 list.Add(*pFamilyName);
319 list.RemoveAll(true);
321 return GetLastResult();
326 typedef Tizen::Graphics::_Font::SystemPixel _SystemPixel;
327 typedef Tizen::Graphics::_Util::ScratchPad<_SystemPixel> _ScratchPad32;
331 _ComposeColor(unsigned long color32, int opacity)
333 unsigned char alpha = (unsigned char) (((color32) >> 24));
334 unsigned char red = (unsigned char) (((color32) >> 16));
335 unsigned char green = (unsigned char) (((color32) >> 8));
336 unsigned char blue = (unsigned char) ((color32));
338 alpha = (unsigned char) ((alpha * opacity + 255) >> 8);
339 red = (unsigned char) ((red * opacity + 255) >> 8);
340 green = (unsigned char) ((green * opacity + 255) >> 8);
341 blue = (unsigned char) ((blue * opacity + 255) >> 8);
343 return (unsigned long) (((unsigned long) (alpha) << 24) | ((unsigned long) (red) << 16) | ((unsigned long) (green) << 8) | (unsigned long) (blue));
347 _SetColor(cairo_t* pCairo, unsigned long composedColor)
349 double a = ((composedColor >> 24) & 0xFF) * 1.0 / 255.0;
350 double r = ((composedColor >> 16) & 0xFF) * 1.0 / 255.0;
351 double g = ((composedColor >> 8) & 0xFF) * 1.0 / 255.0;
352 double b = ((composedColor >> 0) & 0xFF) * 1.0 / 255.0;
354 cairo_set_source_rgba(pCairo, r, g, b, a);
361 return (a < b) ? a : b;
363 #define BLEND_ALPHA_COMPONEMT(srcA, dstA) (_TempMin <unsigned long>((srcA) + (dstA) - (((srcA) * (dstA)) >> 8), 0xFF));
365 struct _NativeGfxEngine
368 cairo_surface_t* pCairoSurface;
379 cairo_destroy(pCairo);
384 cairo_surface_destroy(pCairoSurface);
391 const char* _SampleLanguages[] =
393 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_COMMON
394 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_INHERITED
395 "ar", // G_UNICODE_SCRIPT_ARABIC
396 "hy", // G_UNICODE_SCRIPT_ARMENIAN
397 "bn", // G_UNICODE_SCRIPT_BENGALI
398 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_BOPOMOFO
399 "chr", // G_UNICODE_SCRIPT_CHEROKEE
400 "cop", // G_UNICODE_SCRIPT_COPTIC
401 "ru", // G_UNICODE_SCRIPT_CYRILLIC
402 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_DESERET
403 "hi", // G_UNICODE_SCRIPT_DEVANAGARI
404 "am", // G_UNICODE_SCRIPT_ETHIOPIC
405 "ka", // G_UNICODE_SCRIPT_GEORGIAN
406 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_GOTHIC
407 "el", // G_UNICODE_SCRIPT_GREEK
408 "gu", // G_UNICODE_SCRIPT_GUJARATI
409 "pa", // G_UNICODE_SCRIPT_GURMUKHI
410 "zh", // G_UNICODE_SCRIPT_HAN
411 "ko", // G_UNICODE_SCRIPT_HANGUL
412 "he", // G_UNICODE_SCRIPT_HEBREW
413 "ja", // G_UNICODE_SCRIPT_HIRAGANA
414 "kn", // G_UNICODE_SCRIPT_KANNADA
415 "ja", // G_UNICODE_SCRIPT_KATAKANA
416 "km", // G_UNICODE_SCRIPT_KHMER
417 "lo", // G_UNICODE_SCRIPT_LAO
418 "en", // G_UNICODE_SCRIPT_LATIN
419 "ml", // G_UNICODE_SCRIPT_MALAYALAM
420 "mn", // G_UNICODE_SCRIPT_MONGOLIAN
421 "my", // G_UNICODE_SCRIPT_MYANMAR
422 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_OGHAM
423 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_OLD_ITALIC
424 "or", // G_UNICODE_SCRIPT_ORIYA
425 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_RUNIC
426 "si", // G_UNICODE_SCRIPT_SINHALA
427 "syr", // G_UNICODE_SCRIPT_SYRIAC
428 "ta", // G_UNICODE_SCRIPT_TAMIL
429 "te", // G_UNICODE_SCRIPT_TELUGU
430 "dv", // G_UNICODE_SCRIPT_THAANA
431 "th", // G_UNICODE_SCRIPT_THAI
432 "bo", // G_UNICODE_SCRIPT_TIBETAN
433 "iu", // G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL
434 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_YI
435 "tl", // G_UNICODE_SCRIPT_TAGALOG
436 "hnn", // G_UNICODE_SCRIPT_HANUNOO
437 "bku", // G_UNICODE_SCRIPT_BUHID
438 "tbw", // G_UNICODE_SCRIPT_TAGBANWA
439 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_BRAILLE
440 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_CYPRIOT
441 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_LIMBU
442 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_OSMANYA
443 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_SHAVIAN
444 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_LINEAR_B
445 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_TAI_LE
446 "uga", // G_UNICODE_SCRIPT_UGARITIC
447 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_NEW_TAI_LUE
448 "bug", // G_UNICODE_SCRIPT_BUGINESE
449 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_GLAGOLITIC
450 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_TIFINAGH
451 "syl", // G_UNICODE_SCRIPT_SYLOTI_NAGRI
452 "peo", // G_UNICODE_SCRIPT_OLD_PERSIAN
453 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_KHAROSHTHI
454 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_UNKNOWN
455 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_BALINESE
456 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_CUNEIFORM
457 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_PHOENICIAN
458 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_PHAGS_PA
459 "nqo" // G_UNICODE_SCRIPT_NKO
462 const int _sampleLanguageCount = sizeof(_SampleLanguages) / sizeof(_SampleLanguages[0]);
466 _Util::String textFragment;
469 _TextFragment(const _Util::String& string, _IFont* pFont)
470 : textFragment(string)
479 namespace Tizen { namespace Graphics { namespace _Util
483 inline Tizen::Graphics::_TextBidiProperty::BidiHint Convert<Tizen::Graphics::TextBidiHint, Tizen::Graphics::_TextBidiProperty::BidiHint>(const Tizen::Graphics::TextBidiHint& bidiHint)
487 case TEXT_BIDI_HINT_LTR:
488 return _TextBidiProperty::BIDI_HINT_LTR;
489 case TEXT_BIDI_HINT_RTL:
490 return _TextBidiProperty::BIDI_HINT_RTL;
492 return _TextBidiProperty::BIDI_HINT_NONE;
496 }}} // Tizen::Graphics::_Util
499 namespace Tizen { namespace Graphics
507 _Util::CarveMagicKey(*this, __magicKey);
510 _Font::_Font(const _Font& obj)
513 this->__fontAttrib = obj.__fontAttrib;
514 this->__sharedFont = obj.__sharedFont;
516 _Util::CarveMagicKey(*this, __magicKey);
521 _Util::EraseMagicKey(*this, __magicKey);
525 _Font::Construct(int style, _Util::FixedPoint26_6 pcSize)
527 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
529 // use default system font
530 _FontRsrcManager::SharedFontResource out;
531 result r = mgr.GetFont(style, pcSize, out);
532 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get system default font", GetErrorMessage(r));
536 __UpdateFontAttribute(style, pcSize);
542 _Font::Construct(const Tizen::Base::String& fontName, int style, _Util::FixedPoint26_6 pcSize, bool isPathEnabled)
544 bool systemFont = false;
545 String appFontPath = L"";
546 result r = E_SUCCESS;
548 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
549 _FontRsrcManager::SharedFontResource out;
551 if (!Tizen::App::_AppInfo::IsOspCompat())
553 _Util::WString fontNameTemp(fontName.GetPointer());
554 _Util::WString appFontPathTemp(mgr.FindAppFontName(fontNameTemp));
555 appFontPath.Append(appFontPathTemp.c_str());
558 // check if user want to use a app font
559 if (!appFontPath.IsEmpty())
561 r = mgr.GetFont(appFontPath, style, pcSize, out);
562 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get app font", GetErrorMessage(r));
566 IList* pList = GetSystemFontListN();
571 for (idx = 0; idx < pList->GetCount(); idx++)
573 String* pName = static_cast <String*>(pList->GetAt(idx));
580 if (*pName == fontName)
587 pList->RemoveAll(true);
593 r = mgr.GetSystemFont(fontName, style, pcSize, out);
594 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get system font", GetErrorMessage(r));
596 else if (isPathEnabled)
598 r = mgr.GetFont(fontName, style, pcSize, out);
599 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get font", GetErrorMessage(r));
605 __UpdateFontAttribute(style, pcSize);
611 _Font::Construct(const Tizen::Base::ByteBuffer& fontData, int style, _Util::FixedPoint26_6 pcSize)
613 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
615 const byte* pBuffer = fontData.GetPointer();
616 int buffSize = fontData.GetLimit();
618 _FontRsrcManager::SharedFontResource out;
619 result r = mgr.GetFont(pBuffer, buffSize, style, pcSize, out);
620 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get system font", GetErrorMessage(r));
624 __UpdateFontAttribute(style, pcSize);
630 _Font::IsConstructed(void) const
632 return (__sharedFont.get() != null);
635 _Util::FixedPoint26_6
636 _Font::GetMaxHeight(void) const
638 return __fontAttrib.maxHeight;
641 _Util::FixedPoint26_6
642 _Font::GetMaxWidth(void) const
644 return __fontAttrib.maxWidth;
647 _Util::FixedPoint26_6
648 _Font::GetAscender(void) const
650 return __fontAttrib.ascender;
653 _Util::FixedPoint26_6
654 _Font::GetDescender(void) const
656 return __fontAttrib.descender;
660 _Font::GetLeftBear(wchar_t character, _Util::FixedPoint22_10& leftBear) const
664 _IFont::Glyph* pFontGlyphData = null;
665 LOAD_GLYPH_DATA_CONST(character, pFontGlyphData, E_SYSTEM);
667 // left bear is Glyph::xOffset, set it
668 leftBear = pFontGlyphData->xOffset;
670 UNLOAD_GLYPH_DATA_CONST(pFontGlyphData);
676 _Font::GetRightBear(wchar_t character, _Util::FixedPoint22_10& rightBear) const
680 _IFont::Glyph* pFontGlyphData = null;
681 LOAD_GLYPH_DATA_CONST(character, pFontGlyphData, E_SYSTEM);
683 // right bear is Glyph::xOffset + GlyphBitmap::width, set it
684 rightBear = pFontGlyphData->xOffset + _Util::FixedPoint22_10(pFontGlyphData->image.width);
686 UNLOAD_GLYPH_DATA_CONST(pFontGlyphData);
692 _Font::IsBold(void) const
694 return ((__fontAttrib.style & FONT_STYLE_BOLD) ? true : false);
698 _Font::IsItalic(void) const
700 return ((__fontAttrib.style & FONT_STYLE_ITALIC) ? true : false);
704 _Font::IsPlain(void) const
706 return ((__fontAttrib.style & FONT_STYLE_PLAIN) ? true : false);
710 _Font::IsStrikeOut(void) const
712 return __fontAttrib.strikeout;
716 _Font::IsUnderlined(void) const
718 return __fontAttrib.underline;
721 _Util::FixedPoint26_6
722 _Font::GetSize(void) const
724 return __fontAttrib.size;
728 _Font::SetXExpansion(_Util::FixedPoint26_6 xExpansion)
730 __fontAttrib.xExpansion = xExpansion;
736 _Font::SetStrikeOut(bool strikeout)
738 __fontAttrib.strikeout = strikeout;
742 _Font::SetUnderline(bool underline)
744 __fontAttrib.underline = underline;
748 _Font::SetCharSpace(int pc_space)
750 __fontAttrib.charSpace = pc_space;
754 _Font::GetCharSpace(void) const
756 return __fontAttrib.charSpace;
760 _Font::GetLineThickness(void) const
762 return __fontAttrib.lineThickness;
766 _Font::GetFaceName(void) const
768 _IFont::Property property;
769 GET_FONT_PROPERTY(property, String());
771 return ((property.pFamilyName) ? String(property.pFamilyName) : String());
774 Tizen::Base::Collection::IList*
775 _Font::GetSystemFontListN(void)
777 std::auto_ptr<ArrayList> pList(new (std::nothrow) Tizen::Base::Collection::ArrayList);
778 SysTryReturn(NID_GRP, pList.get(), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
780 result r = _GetSystemFontList(*pList);
781 SysTryReturn(NID_GRP, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
783 return pList.release();
787 _Font::GetFaceName(const Tizen::Base::String& filePath)
789 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
790 _FontRsrcManager::SharedFontResource out;
793 result r = mgr.GetTempFont(filePath, FONT_STYLE_PLAIN, _SYSTEM_DEFAULT_FONT_SIZE, out);
794 SysTryReturn(NID_GRP, r == E_SUCCESS, faceName, r, "[%s] Failed to get font", GetErrorMessage(r));
798 _IFont* pTempFont = out.get();
800 _IFont::Property property;
801 pTempFont->GetFontProperty(property);
802 faceName = String(property.pFamilyName);
809 _Font::GetNativeFont(void) const
811 return __pNativeFont;
818 _Font* pNativeFont = new (std::nothrow) _Font(*this);
819 SysTryReturn(NID_GRP, pNativeFont, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
826 _Font::ApplyAttribute()
828 _IFont::Attrib fontAttrib;
829 bool rtn = __pNativeFont->GetAttrib(fontAttrib);
830 SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to get font attribute");
832 fontAttrib.size = __fontAttrib.size;
833 fontAttrib.style = _IFont::STYLE_NONE;
834 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
835 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
836 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
837 fontAttrib.xExpansion = __fontAttrib.xExpansion;
838 rtn = __pNativeFont->SetAttrib(fontAttrib);
839 SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to set font attribute");
845 _Font::GetTextExtent(int width, const _Util::String& text, bool outline, int& count, Dimension& pcDim) const
847 if (text.pStart == null)
851 SysTryReturn(NID_GRP, false, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The given string is invalid.");
854 if (text.length <= 0)
861 result r = this->__GetTextExtentEx(width, text, outline, count, pcDim);
868 _TextBidiPropertyWithReorder bidiProperty(text.pStart, text.length, _Util::Convert<TextBidiHint, _TextBidiProperty::BidiHint>(_GetTextBidiHint()));
870 if (bidiProperty.HasComplexText())
872 typedef _Util::AccumList<_Util::Pair<int, int> > GapList;
876 result r = this->__GetTextExtentList(bidiProperty, gapList);
885 int determinedCount = -1;
887 for (GapList::Iterator i = gapList.Begin(); i != gapList.End(); ++i)
889 left = (i->first < left) ? i->first : left;
890 right = (i->second > right) ? i->second : right;
892 if (determinedCount < 0 && i->first < width && i->second >= width)
894 if (i != gapList.Begin())
896 if (i - gapList.Begin() - 1 < text.length)
898 determinedCount = bidiProperty.pBidiIndex[i - gapList.Begin() - 1];
902 determinedCount = text.length;
907 determinedCount = bidiProperty.pBidiIndex[0];
912 if (right - left <= width)
914 pcDim.SetSize(right - left, __fontAttrib.size.ToInt());
917 else if (determinedCount > 0 && right - left > 0)
919 int expectedValue = width * text.length / (right - left);
920 int tolerance = _Util::Abs(expectedValue - determinedCount);
921 tolerance = (tolerance == 0) ? 2 : tolerance;
923 int tempCount = expectedValue <= determinedCount ? determinedCount + tolerance : determinedCount + (tolerance * 2);
924 tempCount = tempCount > text.length ? text.length : tempCount;
928 while (right - left > width)
930 _TextBidiPropertyWithReorder determinedBidiProperty(text.pStart, --tempCount, _Util::Convert<TextBidiHint, _TextBidiProperty::BidiHint>(_GetTextBidiHint()));
932 GapList determinedGapList;
934 result r = this->__GetTextExtentList(determinedBidiProperty, determinedGapList);
944 for (GapList::Iterator i = determinedGapList.Begin(); i != determinedGapList.End(); ++i)
946 left = (i->first < left) ? i->first : left;
947 right = (i->second > right) ? i->second : right;
951 pcDim.SetSize(right - left, __fontAttrib.size.ToInt());
964 return this->__GetTextExtent(width, text, outline, count, pcDim);
971 _Font::__GetTextExtentEx(int width, const _Util::String& text, bool outline, int& count, Dimension& pcDim) const
973 int preX1 = 0x7FFFFFFF;
974 int preY1 = 0x7FFFFFFF;
975 int preX2 = -0x7FFFFFFF;
976 int preY2 = -0x7FFFFFFF;
980 int x2 = -0x7FFFFFFF;
981 int y2 = -0x7FFFFFFF;
993 wchar_t leftChar = 0;
995 _IFont::Glyph* pFontGlyphData = 0;
997 _Font* pThis = const_cast <_Font*>(this);
999 APPLY_ATTRIBUTE(E_SYSTEM);
1002 _IFont::SizeProperty sizeProperty;
1003 GET_FONT_SIZE_PROPERTY(sizeProperty, E_SYSTEM);
1005 if (__fontAttrib.style & FONT_STYLE_ITALIC)
1007 italicSpace = (sizeProperty.ascender.ToInt() * 2) >> 4;
1011 _IFont::Property property;
1012 GET_FONT_PROPERTY(property, false);
1014 #ifdef APPLY_BOLD_SPACE
1015 if (__fontAttrib.style & FONT_STYLE_BOLD && property.weightClass < _MEDIUM_FONT_BOLD_WEIGHT)
1017 _IFont::Attrib attr;
1018 pThis->GetAttrib(attr);
1019 boldSpace = static_cast<int>(attr.boldWeight.ToFloat() + 0.5f);
1023 const wchar_t* pText = text.pStart;
1024 int length = text.length;
1026 while (*pText && --length >= 0)
1029 FriBidiCharType type = fribidi_get_bidi_type((FriBidiChar) *pText);
1031 GUnicodeScript script = g_unichar_get_script(*pText);
1033 if (FRIBIDI_IS_LETTER(type) && FRIBIDI_IS_RTL(type))
1037 else if (script == G_UNICODE_SCRIPT_DEVANAGARI || script == G_UNICODE_SCRIPT_BENGALI)
1043 // getting proper _Font instance for the specified text
1044 _IFont* pFont = pThis->__GetFont(*pText);
1046 if (pFont != __pNativeFont)
1048 _IFont::Attrib fontAttrib;
1049 bool rtn = pFont->GetAttrib(fontAttrib);
1050 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to get font attribute");
1052 fontAttrib.size = __fontAttrib.size;
1053 fontAttrib.style = _IFont::STYLE_NONE;
1054 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
1055 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
1056 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
1057 fontAttrib.xExpansion = __fontAttrib.xExpansion;
1058 rtn = pFont->SetAttrib(fontAttrib);
1059 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to set font attribute");
1064 if (pFont->GetKerning(leftChar, *pText, xVec, yVec))
1070 if (pFont->LoadGlyph(*pText++, &pFontGlyphData))
1072 int glyphBoundX1 = curX;
1073 int glyphBoundY1 = curY - pFontGlyphData->yOffset.ToInt();
1074 int glyphBoundX2 = glyphBoundX1 +
1075 ((pFontGlyphData->image.width <= 0) ? pFontGlyphData->xAdvance.ToInt()
1076 : (pFontGlyphData->xOffset.ToInt() + pFontGlyphData->image.width));
1077 int glyphBoundY2 = glyphBoundY1 + pFontGlyphData->image.height;
1079 #ifdef SYNCHRONIZATION_2_0
1080 // adjusting x2 bounds for synchronizing fuctionality with 2.0
1081 glyphBoundX2 = glyphBoundX1 + pFontGlyphData->xAdvance.ToInt() + boldSpace;
1091 _ExpandBounds(glyphBoundX1, glyphBoundY1, x1, y1, x2, y2);
1092 _ExpandBounds(glyphBoundX2, glyphBoundY1, x1, y1, x2, y2);
1093 _ExpandBounds(glyphBoundX1, glyphBoundY2, x1, y1, x2, y2);
1094 _ExpandBounds(glyphBoundX2, glyphBoundY2, x1, y1, x2, y2);
1096 curX += pFontGlyphData->xAdvance.ToInt() + __fontAttrib.charSpace + boldSpace;
1097 curY += pFontGlyphData->yAdvance.ToInt();
1099 pFont->UnloadGlyph(&pFontGlyphData);
1101 // check end condition
1102 // TODO, shkim, BIDI need to be cared
1103 if ((x2 - x1) > width)
1114 leftChar = *(pText - 1);
1118 if (characters == 0)
1120 pcDim.SetSize(0, 0);
1125 SysTryCatch(NID_GRP, preX1 <= preX2 && preY1 <= preY2, pcDim.SetSize(0, 0); count = 0, E_SYSTEM, "[E_SYSTEM] Failed to calculate text extent");
1128 pcDim.width = preX2 - preX1 + italicSpace;
1129 #ifdef SYNCHRONIZATION_2_0
1130 pcDim.height = __fontAttrib.size.ToInt();
1132 pcDim.height = preY2 - preY1;
1133 #endif // SYNCHRONIZATION_2_0
1142 _Font::__GetTextExtent(int width, const _Util::String& text, bool outline, int& count, Dimension& pcDim) const
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 #ifdef APPLY_BOLD_SPACE
1190 _IFont::Property property;
1191 GET_FONT_PROPERTY(property, false);
1193 if (__fontAttrib.style & FONT_STYLE_BOLD && property.weightClass < _MEDIUM_FONT_BOLD_WEIGHT)
1195 _IFont::Attrib attr;
1196 pThis->GetAttrib(attr);
1197 boldSpace = static_cast<int>(attr.boldWeight.ToFloat() + 0.5f);
1201 const wchar_t* pText = text.pStart;
1202 int length = text.length;
1204 while (*pText && --length >= 0)
1206 // getting proper _Font instance for the specified text
1207 _IFont* pFont = pThis->__GetFont(*pText);
1209 if (pFont != __pNativeFont)
1211 _IFont::Attrib fontAttrib;
1212 bool rtn = pFont->GetAttrib(fontAttrib);
1213 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to get font attribute");
1215 fontAttrib.size = __fontAttrib.size;
1216 fontAttrib.style = _IFont::STYLE_NONE;
1217 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
1218 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
1219 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
1220 fontAttrib.xExpansion = __fontAttrib.xExpansion;
1221 rtn = pFont->SetAttrib(fontAttrib);
1222 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to set font attribute");
1227 if (pFont->GetKerning(leftChar, *pText, xVec, yVec))
1233 if (pFont->LoadGlyph(*pText++, &pFontGlyphData))
1235 int glyphBoundX1 = curX;
1236 int glyphBoundY1 = curY - pFontGlyphData->yOffset.ToInt();
1237 int glyphBoundX2 = glyphBoundX1 +
1238 ((pFontGlyphData->image.width <= 0) ? pFontGlyphData->xAdvance.ToInt()
1239 : (pFontGlyphData->xOffset.ToInt() + pFontGlyphData->image.width));
1240 int glyphBoundY2 = glyphBoundY1 + pFontGlyphData->image.height;
1242 #ifdef SYNCHRONIZATION_2_0
1243 // adjusting x2 bounds for synchronizing fuctionality with 2.0
1244 glyphBoundX2 = glyphBoundX1 + pFontGlyphData->xAdvance.ToInt() + boldSpace;
1254 _ExpandBounds(glyphBoundX1, glyphBoundY1, x1, y1, x2, y2);
1255 _ExpandBounds(glyphBoundX2, glyphBoundY1, x1, y1, x2, y2);
1256 _ExpandBounds(glyphBoundX1, glyphBoundY2, x1, y1, x2, y2);
1257 _ExpandBounds(glyphBoundX2, glyphBoundY2, x1, y1, x2, y2);
1259 curX += pFontGlyphData->xAdvance.ToInt() + __fontAttrib.charSpace + boldSpace;
1260 curY += pFontGlyphData->yAdvance.ToInt();
1262 pFont->UnloadGlyph(&pFontGlyphData);
1264 // check end condition
1265 // TODO, shkim, BIDI need to be cared
1266 if ((x2 - x1) > width)
1277 leftChar = *(pText - 1);
1281 if (characters == 0)
1283 pcDim.SetSize(0, 0);
1288 SysTryCatch(NID_GRP, preX1 <= preX2 && preY1 <= preY2, pcDim.SetSize(0, 0); count = 0, E_SYSTEM, "[E_SYSTEM] Failed to calculate text extent");
1291 pcDim.width = preX2 - preX1 + italicSpace;
1292 #ifdef SYNCHRONIZATION_2_0
1293 pcDim.height = __fontAttrib.size.ToInt();
1295 pcDim.height = preY2 - preY1;
1296 #endif // SYNCHRONIZATION_2_0
1305 _Font::GetTextExtent(int width, const _Util::String& text, bool outline, const Tizen::Base::String& delimiter, int& count, Dimension& dim) const
1307 if (text.pStart == null)
1311 SysTryReturn(NID_GRP, false, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The given string is invalid.");
1314 if (text.length <= 0)
1321 const wchar_t* pText = text.pStart;
1322 const wchar_t* pTextEnd = pText + text.length;
1324 while (pText < pTextEnd)
1326 if (*pText == 0x0D || *pText == 0x0A)
1335 return this->GetTextExtent(width, _Util::String(text.pStart, pTextEnd - text.pStart), outline, count, dim);
1339 _Font::__GetTextExtentList(const _Util::String& text, _Util::AccumList<_Util::Pair<int, int> >& outList) const
1343 _Font* pThis = const_cast <_Font*>(this);
1345 APPLY_ATTRIBUTE(E_SYSTEM);
1347 int italicSpace = 0;
1350 #ifdef SYNCHRONIZATION_2_0
1352 _IFont::SizeProperty sizeProperty;
1354 GET_FONT_SIZE_PROPERTY(sizeProperty, E_SYSTEM);
1356 if (__fontAttrib.style & FONT_STYLE_ITALIC)
1358 italicSpace = (sizeProperty.ascender.ToInt() * 2) >> 4;
1363 #ifdef APPLY_BOLD_SPACE
1364 _IFont::Property property;
1365 GET_FONT_PROPERTY(property, false);
1367 if (__fontAttrib.style & FONT_STYLE_BOLD && property.weightClass < _MEDIUM_FONT_BOLD_WEIGHT)
1369 _IFont::Attrib attr;
1371 if (pThis->GetAttrib(attr))
1373 boldSpace = static_cast<int>(attr.boldWeight.ToFloat() + 0.5f);
1380 wchar_t prevChar = 0;
1382 const wchar_t* pText = text.pStart;
1383 int length = text.length;
1387 while (*(++pText) && --length >= 0)
1389 _IFont* pFont = pThis->__GetFont(*pText);
1393 if (pFont != __pNativeFont)
1395 _IFont::Attrib fontAttrib;
1397 if (pFont->GetAttrib(fontAttrib))
1399 fontAttrib.size = __fontAttrib.size;
1400 fontAttrib.style = _IFont::STYLE_NONE;
1401 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
1402 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
1403 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
1404 fontAttrib.xExpansion = __fontAttrib.xExpansion;
1405 pFont->SetAttrib(fontAttrib);
1409 _IFont::Glyph* pFontGlyphData = 0;
1411 if (pFont->LoadGlyph(*pText, &pFontGlyphData))
1413 // When LoadGlyph fails continuously in the original code, there is a problem to check the kerning on the results of the previous prevChar
1419 if (pFont->GetKerning(prevChar, *pText, xVec, yVec))
1427 curX += pFontGlyphData->xAdvance.ToInt() + __fontAttrib.charSpace + boldSpace;
1428 curY += pFontGlyphData->yAdvance.ToInt();
1430 pFont->UnloadGlyph(&pFontGlyphData);
1433 outList.Push(_Util::MakePair(prevX, curX));
1439 // Cannot determine a glyph extent
1441 outList.Push(_Util::MakePair(curX, curX));
1448 _Font::__GetTextExtentList(_TextBidiPropertyWithReorder& bidiProperty, _Util::AccumList<_Util::Pair<int, int> >& outList) const
1450 if (bidiProperty.length <= 0)
1457 _Util::AccumList<_Util::Pair<int, int> > tempList;
1463 int length = bidiProperty.length;
1465 _Font* pThis = const_cast <_Font*>(this);
1467 pThis->ApplyAttribute();
1469 const wchar_t* pReorderedText = bidiProperty.GetReorderedText();
1471 const wchar_t* pTextFragmentBegin = pReorderedText;
1472 const wchar_t* pTextFragmentEnd = pTextFragmentBegin + length;
1474 const wchar_t* pTextSegment = pTextFragmentBegin;
1476 _IFont* pBaseFont = pThis->__GetFont(*pTextSegment);
1478 _Util::AccumList<_TextFragment> textFragmentList;
1480 while (pTextSegment < pTextFragmentEnd)
1482 if (pBaseFont->CheckGlyph(*pTextSegment) == 0)
1484 _IFont* pFallbackFont = pThis->__GetFont(*pTextSegment);
1486 if (pBaseFont != pFallbackFont)
1488 textFragmentList.Push(_TextFragment(_Util::String(pTextFragmentBegin, pTextSegment - pTextFragmentBegin), pBaseFont));
1490 pTextFragmentBegin = pTextSegment;
1491 pBaseFont = pFallbackFont;
1498 textFragmentList.Push(_TextFragment(_Util::String(pTextFragmentBegin, pTextSegment - pTextFragmentBegin), pBaseFont));
1502 * for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.Begin(); textFragment != textFragmentList.End(); ++textFragment)
1505 * for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.End(); textFragment != textFragmentList.Begin(); )
1511 for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.Begin(); textFragment != textFragmentList.End(); ++textFragment)
1513 if (textFragment->pUsingFont == null || textFragment->textFragment.length <= 0)
1518 if (textFragment->pUsingFont != __pNativeFont)
1520 _IFont::Attrib fontAttrib;
1522 if (textFragment->pUsingFont->GetAttrib(fontAttrib))
1524 fontAttrib.size = __fontAttrib.size;
1525 fontAttrib.style = _IFont::STYLE_NONE;
1526 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
1527 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
1528 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
1529 fontAttrib.xExpansion = __fontAttrib.xExpansion;
1530 textFragment->pUsingFont->SetAttrib(fontAttrib);
1534 Tizen::Base::Collection::ArrayListT<_IFont::Glyph *> glyphList;
1536 const wchar_t firstChar = *textFragment->textFragment.pStart;
1538 GUnicodeScript script = _TextBidiUtil::GetUnicodeScript(firstChar);
1539 // need to check if (script < 0 || script >= _sampleLanguageCount) ?
1541 textFragment->pUsingFont->GetGlyphList(textFragment->textFragment, glyphList, script);
1543 int count = glyphList.GetCount();
1545 for (int i = 0; i < count; i++)
1547 _IFont::Glyph *pGlyph = 0;
1549 glyphList.GetAt(i, pGlyph);
1551 // bug fixed in test case of L"\x9a8\x20\x981\x9a0\x635"
1552 //if (pGlyph->xAdvance == 0 && pGlyph->image.width == 0)
1559 xDest += pGlyph->xAdvance.ToInt();
1560 yDest += pGlyph->yAdvance.ToInt();
1562 tempList.Push(_Util::MakePair(prevX, xDest));
1563 outList.Push(_Util::MakePair(-1, -1));
1566 IEnumeratorT<_IFont::Glyph*>* pEnum = glyphList.GetEnumeratorN();
1570 while (pEnum->MoveNext() == E_SUCCESS)
1572 _IFont::Glyph* pGlyph;
1574 pEnum->GetCurrent(pGlyph);
1575 pBaseFont->UnloadGlyph(&pGlyph);
1583 if (bidiProperty.pBidiIndex)
1585 // Reorder list by using BIDI index
1586 typedef _Util::Pair<int, int> Gap;
1587 typedef _Util::AccumList<Gap> GapList;
1589 GapList::Iterator dstBegin = outList.Begin();
1593 if (bidiProperty.length == int(tempList.Size()))
1595 for (GapList::ConstIterator src = tempList.Begin(); src != tempList.End(); ++src)
1597 *(dstBegin + bidiProperty.pBidiIndex[index++]) = *src;
1600 else if (bidiProperty.length > int(tempList.Size()))
1602 _TextBidiUtil::GetReorderedIndexList(bidiProperty, tempList, outList);
1604 else // if (bidiProperty.length < tempList.Size())
1606 // under development
1607 for (GapList::ConstIterator src = tempList.Begin(); src != tempList.End() && index < bidiProperty.length; ++src)
1609 *(dstBegin + bidiProperty.pBidiIndex[index++]) = *src;
1615 typedef _Util::Pair<int, int> Gap;
1616 typedef _Util::AccumList<Gap> GapList;
1618 GapList::Iterator dst = outList.Begin();
1619 GapList::Iterator dstEnd = outList.End();
1621 GapList::ConstIterator src = tempList.Begin();
1622 GapList::ConstIterator srcEnd = tempList.End();
1624 for (; (src != srcEnd) && (dst != dstEnd); ++src, ++dst)
1634 _Font::GetTextExtentList(const _Util::String& text, _Util::AccumList<_Util::Pair<int, int> >& outList) const
1636 if (text.pStart == null)
1639 SysTryReturn(NID_GRP, false, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The given string is invalid.");
1642 if (text.length <= 0)
1648 _TextBidiPropertyWithReorder bidiProperty(text.pStart, text.length, _Util::Convert<TextBidiHint, _TextBidiProperty::BidiHint>(_GetTextBidiHint()));
1650 if (bidiProperty.HasComplexText())
1652 return this->__GetTextExtentList(bidiProperty, outList);
1656 return this->__GetTextExtentList(text, outList);
1663 _Font::SetSize(_Util::FixedPoint26_6 pcSize)
1665 __UpdateFontAttribute(__fontAttrib.style, pcSize);
1671 _Font::SetStyle(int style)
1673 __fontAttrib.style = style;
1679 _Font::GetStyle(void) const
1681 return __fontAttrib.style;
1684 _Util::FixedPoint26_6
1685 _Font::GetLeading(void) const
1688 return __fontAttrib.maxHeight;
1690 return __fontAttrib.ascender - __fontAttrib.descender + __fontAttrib.leading;
1695 _Font::__DrawText(_Canvas& canvas, const Point& point, const _Util::String& text, unsigned long color, bool ignorePredefinedColor)
1697 SysTryReturnResult(NID_GRP, canvas.__pScratchPad != null, E_INVALID_ARG, "A canvas is invalid");
1699 bool rtn = this->ApplyAttribute();
1700 SysTryReturn(NID_GRP, rtn, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fails to apply font attribute.");
1702 _Util::ScratchPad <SystemPixel>& scratchPad = *canvas.__pScratchPad;
1703 scratchPad.RegisterFillRect(_RasterOp::FnFillRectFont32Bit);
1705 Rectangle clipBounds;
1706 canvas.__GetClipBounds(clipBounds);
1708 int xDest = point.x;
1709 int yDest = point.y;
1710 int startX = point.x;
1712 int italicSpace = 0;
1714 int clipX1 = clipBounds.x;
1715 int clipY1 = clipBounds.y;
1716 int clipX2 = clipX1 + clipBounds.width;
1717 int clipY2 = clipY1 + clipBounds.height;
1721 wchar_t leftChar = 0;
1722 _IFont::Glyph* pFontGlyphData = 0;
1724 _IFont::SizeProperty sizeProperty;
1725 rtn = this->GetFontSizeProperty(sizeProperty);
1726 SysTryReturn(NID_GRP, rtn, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to get font sizeProperty.");
1728 // need to revise y value, because _IFont is based on the baseline
1730 if (canvas.__textOrigin == TEXT_ORIGIN_LEFT_TOP)
1732 yDest += sizeProperty.ascender.ToInt();
1735 charHeight = sizeProperty.ascender.ToInt() - sizeProperty.descender.ToInt();
1737 if (this->GetStyle() & FONT_STYLE_ITALIC)
1739 italicSpace = (sizeProperty.ascender.ToInt() * 2) >> 4;
1743 #ifdef APPLY_BOLD_SPACE
1744 _IFont::Property property;
1745 GET_FONT_PROPERTY(property, false);
1747 if (__fontAttrib.style & FONT_STYLE_BOLD && property.weightClass < _MEDIUM_FONT_BOLD_WEIGHT)
1749 _IFont::Attrib attr;
1750 this->GetAttrib(attr);
1751 boldSpace = static_cast<int>(attr.boldWeight.ToFloat() + 0.5f);
1755 const wchar_t* pText = text.pStart;
1756 int length = text.length;
1758 unsigned long canvasFgColor = color;
1760 _TextBidiPropertyWithReorder bidiProperty(pText, length, _Util::Convert<TextBidiHint, _TextBidiProperty::BidiHint>(_GetTextBidiHint()));
1762 if (bidiProperty.HasComplexText())
1764 const wchar_t* pReorderedText = bidiProperty.GetReorderedText();
1766 const wchar_t* pTextFragmentBegin = pReorderedText;
1767 const wchar_t* pTextFragmentEnd = pTextFragmentBegin + length;
1769 const wchar_t* pTextSegment = pTextFragmentBegin;
1771 _IFont* pBaseFont = this->__GetFont(*pTextSegment);
1773 _Util::AccumList<_TextFragment> textFragmentList;
1775 while (pTextSegment < pTextFragmentEnd)
1777 if (pBaseFont->CheckGlyph(*pTextSegment) == 0)
1779 _IFont* pFallbackFont = this->__GetFont(*pTextSegment);
1781 if (pBaseFont != pFallbackFont)
1783 textFragmentList.Push(_TextFragment(_Util::String(pTextFragmentBegin, pTextSegment - pTextFragmentBegin), pBaseFont));
1785 pTextFragmentBegin = pTextSegment;
1786 pBaseFont = pFallbackFont;
1793 textFragmentList.Push(_TextFragment(_Util::String(pTextFragmentBegin, pTextSegment - pTextFragmentBegin), pBaseFont));
1797 * for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.Begin(); textFragment != textFragmentList.End(); ++textFragment)
1800 * for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.End(); textFragment != textFragmentList.Begin(); )
1806 for (_Util::AccumList<_TextFragment>::Iterator textFragment = textFragmentList.Begin(); textFragment != textFragmentList.End(); ++textFragment)
1808 if (textFragment->pUsingFont == null || textFragment->textFragment.length <= 0)
1813 if (textFragment->pUsingFont != __pNativeFont)
1815 _IFont::Attrib fontAttrib;
1817 if (textFragment->pUsingFont->GetAttrib(fontAttrib))
1819 fontAttrib.size = __fontAttrib.size;
1820 fontAttrib.style = _IFont::STYLE_NONE;
1821 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
1822 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
1823 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
1824 fontAttrib.xExpansion = __fontAttrib.xExpansion;
1825 textFragment->pUsingFont->SetAttrib(fontAttrib);
1829 Tizen::Base::Collection::ArrayListT<_IFont::Glyph *> glyphList;
1831 const wchar_t firstChar = *textFragment->textFragment.pStart;
1833 GUnicodeScript script = _TextBidiUtil::GetUnicodeScript(firstChar);
1835 textFragment->pUsingFont->GetGlyphList(textFragment->textFragment, glyphList, script);
1836 // need to check if (script < 0 || script >= _sampleLanguageCount) ?
1838 int count = glyphList.GetCount();
1840 for (int i = 0; i < count; i++)
1843 static int s_index = 0;
1844 const unsigned long COLOR[6] =
1853 unsigned long canvasFgColor = COLOR[s_index++ % 6];
1856 typedef unsigned long TPixel;
1857 _IFont::Glyph *pGlyph = 0;
1859 TPixel srcR, srcG, srcB, srcA;
1860 TPixel dstR, dstG, dstB, dstA;
1862 srcA = (canvasFgColor >> 24) & 0xFF;
1863 srcA += (srcA >> 7);
1864 srcR = (canvasFgColor >> 16) & 0xFF;
1865 srcG = (canvasFgColor >> 8) & 0xFF;
1866 srcB = (canvasFgColor) & 0xFF;
1868 SystemPixel* pBufferStartAddr = null;
1871 scratchPad.GetBuffer(pBufferStartAddr, bufferPitch);
1873 glyphList.GetAt(i, pGlyph);
1875 if (!_TextBidiUtil::IsTextBidiBaseLtr())
1877 xDest -= pGlyph->xAdvance.ToInt();
1878 yDest -= pGlyph->yAdvance.ToInt();
1881 // temporary indent for convenience of code review
1882 switch (pGlyph->image.depth)
1886 for (int h = 0; h < pGlyph->image.height; h++)
1888 int y = yDest - pGlyph->yOffset.ToInt() + h;
1900 TPixel* pDest32 = pBufferStartAddr + y * bufferPitch + xDest + pGlyph->xOffset.ToInt();
1902 for (int w = 0; w < pGlyph->image.width; w++)
1904 int x = xDest + pGlyph->xOffset.ToInt() + w;
1917 unsigned long alpha = (unsigned long) (pGlyph->image.pBitmap[h * pGlyph->image.bytesPerLine + w]);
1921 // equivalent to scratchPad.FillRect(x, y, 1, 1, fgColor, alpha);
1922 alpha = (alpha * srcA) >> 8;
1923 alpha += (alpha >> 7);
1925 dstA = (*pDest32 >> 24) & 0xFF;
1926 dstR = (*pDest32 >> 16) & 0xFF;
1927 dstG = (*pDest32 >> 8) & 0xFF;
1928 dstB = (*pDest32) & 0xFF;
1930 dstA = BLEND_ALPHA_COMPONEMT(alpha, dstA);
1931 dstR = (dstR + (((srcR - dstR) * alpha) >> 8)) & 0xFF;
1932 dstG = (dstG + (((srcG - dstG) * alpha) >> 8)) & 0xFF;
1933 dstB = (dstB + (((srcB - dstB) * alpha) >> 8)) & 0xFF;
1935 *pDest32 = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB;
1946 scratchPad.RegisterFillRect(_RasterOp::FnFillRectAlpha32Bit);
1948 for (int h = 0; h < pFontGlyphData->image.height; h++)
1950 int y = yDest - pFontGlyphData->yOffset.ToInt() + h;
1962 for (int w = 0; w < pFontGlyphData->image.width; w++)
1964 int x = xDest + pFontGlyphData->xOffset.ToInt() + w;
1976 unsigned short* pSource = (unsigned short*)&pFontGlyphData->image.pBitmap[h * pFontGlyphData->image.bytesPerLine];
1979 TPixel dest32 = ((*pSource & 0xF000) << 16) | ((*pSource & 0x0F00) << 12) | ((*pSource & 0x00F0) << 8) | ((*pSource & 0x000F) << 4);
1980 dest32 |= (dest32 >> 4);
1982 scratchPad.FillRect(x, y, 1, 1, dest32, 255);
1985 scratchPad.RegisterFillRect(_RasterOp::FnFillRectFont32Bit);
1991 scratchPad.RegisterFillRect(_RasterOp::FnFillRectAlpha32Bit);
1993 for (int h = 0; h < pGlyph->image.height; h++)
1995 int y = yDest - pGlyph->yOffset.ToInt() + h;
2007 TPixel* pDest32 = pBufferStartAddr + y * bufferPitch + xDest + pGlyph->xOffset.ToInt();
2009 for (int w = 0; w < pGlyph->image.width; w++)
2011 int x = xDest + pGlyph->xOffset.ToInt() + w;
2024 unsigned long* pSource = (unsigned long*)&pGlyph->image.pBitmap[h * pGlyph->image.bytesPerLine];
2027 scratchPad.FillRect(x, y, 1, 1, *pSource, 255);
2031 scratchPad.RegisterFillRect(_RasterOp::FnFillRectFont32Bit);
2037 if (_TextBidiUtil::IsTextBidiBaseLtr())
2039 xDest += pGlyph->xAdvance.ToInt();
2040 yDest += pGlyph->yAdvance.ToInt();
2044 IEnumeratorT<_IFont::Glyph*>* pEnum = glyphList.GetEnumeratorN();
2048 while (pEnum->MoveNext() == E_SUCCESS)
2050 _IFont::Glyph* pGlyph;
2052 pEnum->GetCurrent(pGlyph);
2053 pBaseFont->UnloadGlyph(&pGlyph);
2062 while (*pText && --length >= 0)
2064 // find out proper native font
2065 _IFont* pFont = this->__GetFont(*pText);
2072 if (pFont != __pNativeFont)
2074 _IFont::Attrib fontAttrib;
2075 bool rtn = pFont->GetAttrib(fontAttrib);
2076 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to get font attribute");
2078 fontAttrib.size = __fontAttrib.size;
2079 fontAttrib.style = _IFont::STYLE_NONE;
2080 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
2081 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
2082 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
2083 fontAttrib.xExpansion = __fontAttrib.xExpansion;
2084 rtn = pFont->SetAttrib(fontAttrib);
2085 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to set font attribute");
2088 _IFont::Property property;
2089 pFont->GetFontProperty(property);
2091 unsigned long fgColor = (!ignorePredefinedColor && pFont->hasPredefinedColor()) ? _GetPredefinedColor(*pText, canvasFgColor) : canvasFgColor;
2095 if (pFont->GetKerning(leftChar, *pText, xVec, yVec))
2101 bool rtn = pFont->LoadGlyph(*pText++, &pFontGlyphData);
2108 typedef unsigned long TPixel;
2110 // temporary indent for convenience of code review
2111 switch (pFontGlyphData->image.depth)
2115 TPixel srcA = (fgColor >> 24) & 0xFF;
2116 srcA += (srcA >> 7);
2118 TPixel srcR = (fgColor >> 16) & 0xFF;
2119 TPixel srcG = (fgColor >> 8) & 0xFF;
2120 TPixel srcB = (fgColor) & 0xFF;
2122 SystemPixel* pBufferStartAddr = null;
2123 int bufferPitch = 0;
2125 scratchPad.GetBuffer(pBufferStartAddr, bufferPitch);
2127 for (int h = 0; h < pFontGlyphData->image.height; h++)
2129 int y = yDest - pFontGlyphData->yOffset.ToInt() + h;
2141 TPixel* pDest32 = pBufferStartAddr + y * bufferPitch + xDest + pFontGlyphData->xOffset.ToInt();
2143 for (int w = 0; w < pFontGlyphData->image.width; w++)
2145 int x = xDest + pFontGlyphData->xOffset.ToInt() + w;
2158 unsigned long alpha = (unsigned long) (pFontGlyphData->image.pBitmap[h * pFontGlyphData->image.bytesPerLine + w]);
2162 // equivalent to scratchPad.FillRect(x, y, 1, 1, fgColor, alpha);
2163 alpha = (alpha * srcA) >> 8;
2164 alpha += (alpha >> 7);
2166 TPixel dstA = (*pDest32 >> 24) & 0xFF;
2167 TPixel dstR = (*pDest32 >> 16) & 0xFF;
2168 TPixel dstG = (*pDest32 >> 8) & 0xFF;
2169 TPixel dstB = (*pDest32) & 0xFF;
2171 dstA = BLEND_ALPHA_COMPONEMT(alpha, dstA);
2172 dstR = (dstR + (((srcR - dstR) * alpha) >> 8)) & 0xFF;
2173 dstG = (dstG + (((srcG - dstG) * alpha) >> 8)) & 0xFF;
2174 dstB = (dstB + (((srcB - dstB) * alpha) >> 8)) & 0xFF;
2176 *pDest32 = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB;
2183 xDest += pFontGlyphData->xAdvance.ToInt() + __fontAttrib.charSpace + boldSpace;
2184 yDest += pFontGlyphData->yAdvance.ToInt();
2186 leftChar = *(pText - 1);
2188 pFont->UnloadGlyph(&pFontGlyphData);
2194 scratchPad.RegisterFillRect(_RasterOp::FnFillRectAlpha32Bit);
2196 for (int h = 0; h < pFontGlyphData->image.height; h++)
2198 int y = yDest - pFontGlyphData->yOffset.ToInt() + h;
2210 for (int w = 0; w < pFontGlyphData->image.width; w++)
2212 int x = xDest + pFontGlyphData->xOffset.ToInt() + w;
2224 unsigned short* pSource = (unsigned short*)&pFontGlyphData->image.pBitmap[h * pFontGlyphData->image.bytesPerLine];
2227 TPixel dest32 = ((*pSource & 0xF000) << 16) | ((*pSource & 0x0F00) << 12) | ((*pSource & 0x00F0) << 8) | ((*pSource & 0x000F) << 4);
2228 dest32 |= (dest32 >> 4);
2230 scratchPad.FillRect(x, y, 1, 1, dest32, 255);
2234 xDest += pFontGlyphData->xAdvance.ToInt() + __fontAttrib.charSpace + boldSpace;
2235 yDest += pFontGlyphData->yAdvance.ToInt();
2237 leftChar = *(pText - 1);
2239 pFont->UnloadGlyph(&pFontGlyphData);
2241 scratchPad.RegisterFillRect(_RasterOp::FnFillRectFont32Bit);
2247 scratchPad.RegisterFillRect(_RasterOp::FnFillRectAlpha32Bit);
2249 for (int h = 0; h < pFontGlyphData->image.height; h++)
2251 int y = yDest - pFontGlyphData->yOffset.ToInt() + h;
2263 for (int w = 0; w < pFontGlyphData->image.width; w++)
2265 int x = xDest + pFontGlyphData->xOffset.ToInt() + w;
2277 unsigned long* pSource = (unsigned long*)&pFontGlyphData->image.pBitmap[h * pFontGlyphData->image.bytesPerLine];
2280 scratchPad.FillRect(x, y, 1, 1, *pSource, 255);
2284 xDest += pFontGlyphData->xAdvance.ToInt() + __fontAttrib.charSpace + boldSpace;
2285 yDest += pFontGlyphData->yAdvance.ToInt();
2287 leftChar = *(pText - 1);
2289 pFont->UnloadGlyph(&pFontGlyphData);
2291 scratchPad.RegisterFillRect(_RasterOp::FnFillRectFont32Bit);
2299 if (this->IsUnderlined() || this->IsStrikeOut())
2302 int thick = this->GetLineThickness();
2304 if (canvas.__textOrigin == TEXT_ORIGIN_LEFT_TOP)
2306 y = point.y + charHeight - 1;
2310 y = point.y - sizeProperty.descender.ToInt() - 1;
2313 xDest -= this->GetCharSpace();
2315 if (this->IsUnderlined())
2317 canvas.FillRectangle(canvasFgColor, Rectangle(startX, y - thick, xDest - startX, thick));
2320 if (this->IsStrikeOut())
2322 y -= charHeight / 2;
2323 canvas.FillRectangle(canvasFgColor, Rectangle(startX, y - thick, xDest - startX, thick));
2327 scratchPad.RegisterFillRect(null);
2332 #undef BLEND_ALPHA_COMPONEMT
2335 _Font::__DrawText(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length)
2337 _Util::String utilText(text.GetPointer(), text.GetLength(), startIndex, length);
2339 return this->__DrawText(canvas, point, utilText, canvas.__fgColor, false);
2343 _Font::__DrawText(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length, const Color& outlineColor)
2345 unsigned long textColor32 = canvas.__fgColor;
2346 unsigned long outlineColor32 = outlineColor.GetRGB32();;
2348 _Util::String utilText(text.GetPointer(), text.GetLength(), startIndex, length);
2350 this->__DrawText(canvas, Point(point.x - 1, point.y), utilText, outlineColor32, true);
2351 this->__DrawText(canvas, Point(point.x + 1, point.y), utilText, outlineColor32, true);
2352 this->__DrawText(canvas, Point(point.x, point.y - 1), utilText, outlineColor32, true);
2353 this->__DrawText(canvas, Point(point.x, point.y + 1), utilText, outlineColor32, true);
2355 this->__DrawText(canvas, point, utilText, textColor32, false);
2361 _Font::SetAttrib(const _IFont::Attrib& fontAttrib)
2363 return __pNativeFont->SetAttrib(fontAttrib);
2367 _Font::GetAttrib(_IFont::Attrib& fontAttrib) const
2369 return __pNativeFont->GetAttrib(fontAttrib);
2373 _Font::GetKerning(unsigned long character1, unsigned long character2, long& xVector, long& yVector) const
2375 return __pNativeFont->GetKerning(character1, character2, xVector, yVector);
2379 _Font::GetFontSizeProperty(_IFont::SizeProperty& sizeProperty) const
2381 return __pNativeFont->GetFontSizeProperty(sizeProperty);
2385 _Font::LoadGlyph(unsigned long character, _IFont::Glyph** ppFontGlyphData)
2387 // note! we assume that the font attribute has been already applied on _IFont
2390 // if not, loading glyph (character/size/style) and caching it
2391 rtn = __pNativeFont->LoadGlyph(character, ppFontGlyphData);
2392 SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to load glyph data");
2394 // return cached glyph
2399 _Font::UnloadGlyph(_IFont::Glyph** ppFontGlyphData)
2401 return __pNativeFont->UnloadGlyph(ppFontGlyphData);
2405 _Font::CheckGlyph(unsigned long character)
2407 return __pNativeFont->CheckGlyph(character);
2411 _Font::GetFontSizeFromMaxHeight(const _Util::FixedPoint26_6 expectedMaxHeight)
2413 return __pNativeFont->GetFontSizeFromMaxHeight(expectedMaxHeight);
2417 _Font::GetFontSizeFromMaxHeight(int style, const _Util::FixedPoint26_6 expectedMaxHeight)
2419 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
2420 _FontRsrcManager::SharedFontResource out;
2422 result r = mgr.GetFont(style, expectedMaxHeight, out);
2423 SysTryReturn(NID_GRP, r == E_SUCCESS, -1.0f, r, "[%s] Getting system default font failed.", GetErrorMessage(r));
2425 _IFont* pTempFont = out.get();
2427 return pTempFont->GetFontSizeFromMaxHeight(expectedMaxHeight);
2431 _Font::GetFontSizeFromMaxHeight(const Tizen::Base::String& fontName, int style, const _Util::FixedPoint26_6 expectedMaxHeight)
2433 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
2434 _FontRsrcManager::SharedFontResource out;
2436 result r = mgr.GetFont(fontName, style, expectedMaxHeight, out);
2437 SysTryReturn(NID_GRP, r == E_SUCCESS, -1.0f, r, "[%s] Getting font failed.", GetErrorMessage(r));
2439 _IFont* pTempFont = out.get();
2441 return pTempFont->GetFontSizeFromMaxHeight(expectedMaxHeight);
2445 _Font::__UpdateFontAttribute(int style, _Util::FixedPoint26_6 pcSize)
2447 __fontAttrib.style = style;
2448 __fontAttrib.size = pcSize;
2449 __fontAttrib.lineThickness = pcSize.ToInt() > 0 ? (pcSize.ToInt() / 24) + 1 : 1;
2451 _IFont::SizeProperty sizeProperty;
2452 bool getProperty = false;
2454 if (this->ApplyAttribute())
2456 getProperty = __pNativeFont->GetFontSizeProperty(sizeProperty);
2461 __fontAttrib.maxWidth = sizeProperty.maxWidth;
2462 __fontAttrib.maxHeight = sizeProperty.maxHeight;
2463 __fontAttrib.ascender = sizeProperty.ascender;
2464 __fontAttrib.descender = sizeProperty.descender;
2465 __fontAttrib.leading = sizeProperty.leading;
2469 // if failed to get property above, each property should be remained as default: -1
2470 SysLog(NID_GRP, "[] Failed to get font attribute from native font");
2472 __fontAttrib.maxWidth.Reset(0);
2473 __fontAttrib.maxHeight.Reset(0);
2474 __fontAttrib.ascender.Reset(0);
2475 __fontAttrib.descender.Reset(0);
2476 __fontAttrib.leading.Reset(0);
2481 _Font::__DrawTextLastFallback(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length)
2487 _Font::__DrawTextDefault(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length)
2489 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
2490 result r = mgr.GetDefaultSystemFont().__DrawText(canvas, point, text, startIndex, length);
2491 SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Failed to draw default system font", GetErrorMessage(r));
2496 _Font::__DrawTextLastFallback(canvas, point, text, startIndex, length);
2501 _Font::__DrawTextDefault(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length, const Color& outlineColor)
2503 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
2504 result r = mgr.GetDefaultSystemFont().__DrawText(canvas, point, text, startIndex, length, outlineColor);
2505 SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Failed to draw default system font", GetErrorMessage(r));
2510 _Font::__DrawTextLastFallback(canvas, point, text, startIndex, length);
2516 _Font::DrawText(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length)
2518 if (canvas.__pPriorityFont)
2520 return canvas.__pPriorityFont->__DrawText(canvas, point, text, startIndex, length);
2522 else if (canvas.__pFont)
2524 return canvas.__pFont->__DrawText(canvas, point, text, startIndex, length);
2528 return _Font::__DrawTextDefault(canvas, point, text, startIndex, length);
2533 _Font::DrawText(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length, const Color& outlineColor)
2535 if (canvas.__pPriorityFont)
2537 return canvas.__pPriorityFont->__DrawText(canvas, point, text, startIndex, length, outlineColor);
2539 else if (canvas.__pFont)
2541 return canvas.__pFont->__DrawText(canvas, point, text, startIndex, length, outlineColor);
2545 return _Font::__DrawTextDefault(canvas, point, text, startIndex, length, outlineColor);
2552 _Font::GetInstance(_FontImpl& font)
2554 return (&font != null) ? font._pNativeFont : null;
2558 _Font::GetInstance(const _FontImpl& font)
2560 return (&font != null) ? font._pNativeFont : null;
2564 _Font::__GetFont(wchar_t character)
2566 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
2568 if (!_HasEmoticonImage(character))
2570 //------------------------------------------------------
2572 // 1. check if this font has a requested glyph
2574 //------------------------------------------------------
2575 unsigned long idx = __pNativeFont->CheckGlyph(character);
2579 return __pNativeFont;
2582 // Check the BlackList
2583 if (mgr.SearchBlackList(character))
2585 return __pNativeFont;
2589 //------------------------------------------------------
2591 // 1-2. check if this glyph is in the fallback list.
2593 //------------------------------------------------------
2594 _IFont::FontMapT* pFallbackFontMap = __pNativeFont->GetFallbackMap();
2596 #ifdef USE_HASHMAP_FOR_FONT
2597 std::auto_ptr<IMapEnumeratorT<_Util::WString, _FontRsrcManager::SharedFontResource> > enumerator(pFallbackFontMap->GetMapEnumeratorN());
2599 while (enumerator->MoveNext() == E_SUCCESS)
2601 _FontRsrcManager::SharedFontResource pTempFont;
2603 if (enumerator->GetValue(pTempFont) == E_SUCCESS)
2605 _Util::WString key(L"");
2606 result r = enumerator->GetKey(key);
2610 if (mgr.SearchFont(key))
2612 if (pTempFont->CheckGlyph(character) > 0)
2614 return pTempFont.get();
2619 pFallbackFontMap->Remove(key);
2625 for (_IFont::FontMapT::const_iterator fontIterator = pFallbackFontMap->begin(); fontIterator != pFallbackFontMap->end(); ++fontIterator)
2627 if (fontIterator->second != null)
2629 if (fontIterator->second->CheckGlyph(character) > 0)
2631 return fontIterator->second.get();
2637 //------------------------------------------------------
2639 // 2. Get fallback font list via fontconfig
2641 //------------------------------------------------------
2642 Tizen::Base::Collection::ArrayListT<String> fileList;
2643 bool rtn = __GetFallbackFontFileList(character, fileList);
2647 // if failed find out fallback font,
2648 // just use this instance for drawing something for unknown glyph
2649 return __pNativeFont;
2652 //------------------------------------------------------
2654 // 3. try to find a font having a requested glyph
2656 //------------------------------------------------------
2658 _IFont* pFallbackFont = null;
2660 _FontRsrcManager::SharedFontResource out;
2662 int count = fileList.GetCount();
2663 result r = E_FAILURE;
2665 for (int i = 0; i < count; i++)
2667 fileList.GetAt(i, fontName);
2669 if (fontName.IsEmpty())
2674 r = mgr.GetTempFont(fontName, __fontAttrib.style, __fontAttrib.size, out);
2678 unsigned long idx = out->CheckGlyph(character);
2682 _Util::WString fontNameTemp(fontName.GetPointer());
2685 #ifdef USE_HASHMAP_FOR_FONT
2686 r = pFallbackFontMap->Add(fontNameTemp, out);
2688 if (r == E_OBJ_ALREADY_EXIST)
2690 pFallbackFont = out.get();
2694 SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
2696 pFallbackFontMap->push_back(std::make_pair(fontNameTemp, out));
2698 r = mgr.AddFont(fontNameTemp, out);
2699 SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
2701 pFallbackFont = out.get();
2707 if (pFallbackFont == null)
2709 mgr.AddBlackList(character);
2711 return __pNativeFont;
2714 return pFallbackFont;
2717 // if failed find out fallback font,
2718 // just use this instance for drawing something for unknown glyph
2719 return __pNativeFont;
2723 _Font::__GetFallbackFontFileList(wchar_t character, Tizen::Base::Collection::IListT<String>& out)
2725 if (_HasEmoticonImage(character))
2727 out.Add(String(_GetVirtualFileNameForEmoticon()));
2731 GUnicodeScript script = g_unichar_get_script(character);
2732 if (script < 0 || script >= _sampleLanguageCount)
2737 FcPattern* pPattern = null;
2738 FcFontSet* pSet = null;
2739 FcChar8* pName = null;
2740 FcResult res = FcResultNoMatch;
2741 const int fcWeight = (__fontAttrib.style & FONT_STYLE_BOLD) ? FC_WEIGHT_BOLD : FC_WEIGHT_REGULAR;
2743 // getting fallback font list
2744 pPattern = FcPatternBuild(NULL, FC_WEIGHT, FcTypeInteger, fcWeight, NULL);
2745 SysTryCatch(NID_GRP, pPattern, , E_SYSTEM, "[E_SYSTEM] Failed to FcPatternBuild()");
2747 FcPatternAddString(pPattern, FC_FAMILY, (FcChar8*)"Tizen");
2749 if (strncmp(SAMPLE_LANGUAGE_EMPTY, _SampleLanguages[script], strlen(SAMPLE_LANGUAGE_EMPTY) + 1) != 0)
2751 FcPatternAddString(pPattern, FC_LANG, (FcChar8*)_SampleLanguages[script]);
2754 FcConfigSubstitute(NULL, pPattern, FcMatchPattern);
2755 FcDefaultSubstitute(pPattern);
2758 pSet = FcFontSort(NULL, pPattern, FcTrue, NULL, &res);
2759 SysTryCatch(NID_GRP, pSet, , E_SYSTEM, "[E_SYSTEM] Failed to FcFontSort()");
2763 for (int i = 0; i < pSet->nfont; i++)
2765 if (FcPatternGetString(pSet->fonts[i], FC_FILE, 0, &pName) == FcResultMatch)
2767 out.Add(String((char*)pName));
2772 FcFontSetDestroy(pSet);
2773 FcPatternDestroy(pPattern);
2775 return (out.GetCount() > 0) ? true : false;
2779 FcFontSetDestroy(pSet);
2782 if (pPattern != null)
2784 FcPatternDestroy(pPattern);
2791 _Font::UpdateDefaultFont(const String& key)
2795 SysLog(NID_GRP, "Request to change the default font");
2797 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
2799 return mgr.ReloadDefaultSystemFont();
2805 }} // Tizen::Graphics