2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
5 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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"
30 #include <unique_ptr.h>
33 #include <fontconfig/fontconfig.h>
34 #include <pango/pangocairo.h>
35 #include <unicode/uloc.h>
37 #include <FApp_AppInfo.h>
39 #include <FBaseByteBuffer.h>
40 #include <FBaseColArrayList.h>
41 #include <FBaseColIList.h>
42 #include <FBaseUtilStringUtil.h>
43 #include <FGrpDimension.h>
44 #include <FGrpPoint.h>
45 #include <FGrpRectangle.h>
47 #include <FBaseSysLog.h>
48 #include <FSys_EnvironmentImpl.h>
50 #include "FGrp_FontImpl.h"
52 #include "FGrp_CanvasRasterOp.h"
53 #include "FGrp_FontRsrcManager.h"
54 #include "FGrp_FontBidiManager.h"
56 #include "FGrp_Canvas.h"
58 #include "util/FGrp_UtilTemplate.h"
61 #define SYNCHRONIZATION_2_0
62 #define __pNativeFont __sharedFont.get()
63 #define CONVERT_INTEGER_TO_26_6_FIXED_POINT(value) (value * 64)
64 #define CONVERT_26_6_FIXED_POINT_TO_INTEGER(value) (value / 64)
65 #define IF_NOT_INITIALIZED(code) \
66 if (__pNativeFont == null) \
70 #define GET_FONT_PROPERTY(prop, rtnValue) \
72 bool rtn = __pNativeFont->GetFontProperty(prop); \
73 SysTryReturn(NID_GRP, rtn, rtnValue, E_SYSTEM, "[E_SYSTEM] Failed to get font property"); \
75 #define LOAD_GLYPH_DATA_CONST(character, pFontGlyphData, rtnValue) \
77 _Font* pThis = const_cast <_Font*>(this); \
78 bool rtn = pThis->LoadGlyph(character, &pFontGlyphData); \
79 SysTryReturn(NID_GRP, rtn, rtnValue, E_SYSTEM, "[E_SYSTEM] Failed to load glyph data"); \
81 #define UNLOAD_GLYPH_DATA_CONST(pFontGlyphData) \
83 _Font* pThis = const_cast <_Font*>(this); \
84 pThis->UnloadGlyph(&pFontGlyphData); \
86 #define APPLY_ATTRIBUTE(rtnValue) \
88 _Font* pFont = const_cast <_Font*>(this); \
89 bool rtn = pFont->ApplyAttribute(); \
90 SysTryReturn(NID_GRP, rtn, rtnValue, E_SYSTEM, "[E_SYSTEM] Failed to apply font attribute"); \
92 #define SAMPLE_LANGUAGE_EMPTY ""
95 using namespace Tizen::Base;
96 using namespace Tizen::Base::Collection;
97 using namespace Tizen::Base::Utility;
98 using namespace Tizen::Graphics;
99 using namespace Tizen::Io;
100 using namespace Tizen::System;
105 const int _SYSTEM_DEFAULT_FONT_SIZE = CONVERT_INTEGER_TO_26_6_FIXED_POINT(16);
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 FcPattern* pPattern = null;
136 FcFontSet* pSet = null;
137 FcObjectSet* pObjectSet = null;
138 const char* pLang = null;
139 const char* fcStyle = "Regular";
141 // initialize fontconfig library
142 FcBool rtn = FcInit();
143 SysTryCatch(NID_GRP, rtn, , E_SYSTEM, "[E_SYSTEM] Failed to init fontconfig");
145 pPattern = FcPatternCreate();
146 SysTryCatch(NID_GRP, pPattern, , E_SYSTEM, "[E_SYSTEM] Failed to FcPatternCreate()");
148 // language and style
149 FcPatternAddString(pPattern, FC_STYLE, (FcChar8*)fcStyle);
151 // RFC3066 formatted 2-level language identifier will be returned.
152 // e.g., en-NR, ar-SD, byn, tig etc.
153 // but, fontconfig only need 1-level language identifier having maximum 3 letters.
154 pLang = uloc_getDefault();
158 char lang3Letters[4] = {0,};
159 strncpy(lang3Letters, pLang, 3);
161 for (int i = 0; i < 3; i++)
163 if (lang3Letters[i] == '-' || lang3Letters[i] == '_')
170 FcPatternAddString(pPattern, FC_LANG, (FcChar8*)lang3Letters);
173 pObjectSet = FcObjectSetBuild(FC_FAMILY, FC_STYLE, FC_FILE, NULL);
174 SysTryCatch(NID_GRP, pObjectSet, , E_SYSTEM, "[E_SYSTEM] Failed to FcObjectSetBuild()");
176 pSet = FcFontList(NULL, pPattern, pObjectSet);
177 SysTryCatch(NID_GRP, pSet, , E_SYSTEM, "[E_SYSTEM] Failed to init fontconfig");
180 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
181 String defaultFontFaceName(mgr.GetDefaultSystemFont().GetFaceName());
183 bool defaultFontExists = false;
185 list.RemoveAll(true);
186 FcChar8* pName = null;
188 for (int i = 0; i < pSet->nfont; i++)
190 if (FcPatternGetString(pSet->fonts[i], FC_FILE, 0, &pName) == FcResultMatch)
192 String* pFamilyName = new (std::nothrow) String(Tizen::Graphics::_Font::GetFaceName(String((char*)pName)));
193 SysTryCatch(NID_GRP, pFamilyName, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocated memory");
195 list.Add(*pFamilyName);
197 if (*pFamilyName == defaultFontFaceName)
199 defaultFontExists = true;
204 if (defaultFontExists == false)
206 String* pDefaultFontName = new (std::nothrow) String(defaultFontFaceName);
207 SysTryCatch(NID_GRP, pDefaultFontName, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocated memory");
209 list.InsertAt(*pDefaultFontName, 0);
214 FcFontSetDestroy(pSet);
215 FcObjectSetDestroy(pObjectSet);
216 FcPatternDestroy(pPattern);
222 list.RemoveAll(true);
224 // destroy, but before doing that check if those value has been created or not.
227 FcFontSetDestroy(pSet);
232 FcObjectSetDestroy(pObjectSet);
237 FcPatternDestroy(pPattern);
242 return GetLastResult();
245 typedef Tizen::Graphics::_Font::SystemPixel _SystemPixel;
246 typedef Tizen::Graphics::_Util::ScratchPad<_SystemPixel> _ScratchPad32;
250 _ComposeColor(unsigned long color32, int opacity)
252 unsigned char alpha = (unsigned char) (((color32) >> 24));
253 unsigned char red = (unsigned char) (((color32) >> 16));
254 unsigned char green = (unsigned char) (((color32) >> 8));
255 unsigned char blue = (unsigned char) ((color32));
257 alpha = (unsigned char) ((alpha * opacity + 255) >> 8);
258 red = (unsigned char) ((red * opacity + 255) >> 8);
259 green = (unsigned char) ((green * opacity + 255) >> 8);
260 blue = (unsigned char) ((blue * opacity + 255) >> 8);
262 return (unsigned long) (((unsigned long) (alpha) << 24) | ((unsigned long) (red) << 16) | ((unsigned long) (green) << 8) | (unsigned long) (blue));
266 _SetColor(cairo_t* pCairo, unsigned long composedColor)
268 double a = ((composedColor >> 24) & 0xFF) * 1.0 / 255.0;
269 double r = ((composedColor >> 16) & 0xFF) * 1.0 / 255.0;
270 double g = ((composedColor >> 8) & 0xFF) * 1.0 / 255.0;
271 double b = ((composedColor >> 0) & 0xFF) * 1.0 / 255.0;
273 cairo_set_source_rgba(pCairo, r, g, b, a);
280 return (a < b) ? a : b;
282 #define BLEND_ALPHA_COMPONEMT(srcA, dstA) (_TempMin <unsigned long>((srcA) + (dstA) - (((srcA) * (dstA)) >> 8), 0xFF));
284 struct _NativeGfxEngine
287 cairo_surface_t* pCairoSurface;
298 cairo_destroy(pCairo);
303 cairo_surface_destroy(pCairoSurface);
310 const char* _SampleLanguages[] =
312 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_COMMON
313 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_INHERITED
314 "ar", // G_UNICODE_SCRIPT_ARABIC
315 "hy", // G_UNICODE_SCRIPT_ARMENIAN
316 "bn", // G_UNICODE_SCRIPT_BENGALI
317 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_BOPOMOFO
318 "chr", // G_UNICODE_SCRIPT_CHEROKEE
319 "cop", // G_UNICODE_SCRIPT_COPTIC
320 "ru", // G_UNICODE_SCRIPT_CYRILLIC
321 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_DESERET
322 "hi", // G_UNICODE_SCRIPT_DEVANAGARI
323 "am", // G_UNICODE_SCRIPT_ETHIOPIC
324 "ka", // G_UNICODE_SCRIPT_GEORGIAN
325 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_GOTHIC
326 "el", // G_UNICODE_SCRIPT_GREEK
327 "gu", // G_UNICODE_SCRIPT_GUJARATI
328 "pa", // G_UNICODE_SCRIPT_GURMUKHI
329 "zh", // G_UNICODE_SCRIPT_HAN
330 "ko", // G_UNICODE_SCRIPT_HANGUL
331 "he", // G_UNICODE_SCRIPT_HEBREW
332 "ja", // G_UNICODE_SCRIPT_HIRAGANA
333 "kn", // G_UNICODE_SCRIPT_KANNADA
334 "ja", // G_UNICODE_SCRIPT_KATAKANA
335 "km", // G_UNICODE_SCRIPT_KHMER
336 "lo", // G_UNICODE_SCRIPT_LAO
337 "en", // G_UNICODE_SCRIPT_LATIN
338 "ml", // G_UNICODE_SCRIPT_MALAYALAM
339 "mn", // G_UNICODE_SCRIPT_MONGOLIAN
340 "my", // G_UNICODE_SCRIPT_MYANMAR
341 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_OGHAM
342 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_OLD_ITALIC
343 "or", // G_UNICODE_SCRIPT_ORIYA
344 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_RUNIC
345 "si", // G_UNICODE_SCRIPT_SINHALA
346 "syr", // G_UNICODE_SCRIPT_SYRIAC
347 "ta", // G_UNICODE_SCRIPT_TAMIL
348 "te", // G_UNICODE_SCRIPT_TELUGU
349 "dv", // G_UNICODE_SCRIPT_THAANA
350 "th", // G_UNICODE_SCRIPT_THAI
351 "bo", // G_UNICODE_SCRIPT_TIBETAN
352 "iu", // G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL
353 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_YI
354 "tl", // G_UNICODE_SCRIPT_TAGALOG
355 "hnn", // G_UNICODE_SCRIPT_HANUNOO
356 "bku", // G_UNICODE_SCRIPT_BUHID
357 "tbw", // G_UNICODE_SCRIPT_TAGBANWA
358 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_BRAILLE
359 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_CYPRIOT
360 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_LIMBU
361 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_OSMANYA
362 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_SHAVIAN
363 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_LINEAR_B
364 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_TAI_LE
365 "uga", // G_UNICODE_SCRIPT_UGARITIC
366 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_NEW_TAI_LUE
367 "bug", // G_UNICODE_SCRIPT_BUGINESE
368 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_GLAGOLITIC
369 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_TIFINAGH
370 "syl", // G_UNICODE_SCRIPT_SYLOTI_NAGRI
371 "peo", // G_UNICODE_SCRIPT_OLD_PERSIAN
372 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_KHAROSHTHI
373 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_UNKNOWN
374 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_BALINESE
375 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_CUNEIFORM
376 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_PHOENICIAN
377 SAMPLE_LANGUAGE_EMPTY, // G_UNICODE_SCRIPT_PHAGS_PA
378 "nqo" // G_UNICODE_SCRIPT_NKO
381 const int _sampleLanguageCount = sizeof(_SampleLanguages) / sizeof(_SampleLanguages[0]);
384 GetPredefinedColor(const wchar_t unicode, unsigned long fgColor)
388 // Emoji Unicode List 176 + 76
390 static const unsigned long _EMOJI_BLACK = 0xFF000000;
391 static const unsigned long _EMOJI_BLUE = 0xFF0000FF;
392 static const unsigned long _EMOJI_GREEN = 0xFF00FF00;
393 static const unsigned long _EMOJI_RED = 0xFFFF0000;
394 static const unsigned long _EMOJI_ORANGE = 0xFFFF6600;
395 static const unsigned long _EMOJI_PURPLE = 0xFF9370DB;
396 static const unsigned long _EMOJI_DEEP_PURPLE = 0xFF800080;
397 static const unsigned long _EMOJI_DARK_BLUE = 0xFF00008B;
398 static const unsigned long _EMOJI_BROWN = 0xFFA52A2A;
399 static const unsigned long _NOT_EMOJI = 0;
401 static const long _MAX_EMOJI_UNICODE = 0xE757;
402 static const long _MIN_EMOJI_UNICODE = 0xE63E;
404 static const unsigned long _emojiTable[] =
406 _EMOJI_RED, _EMOJI_BLUE, _EMOJI_BLUE, _EMOJI_BLUE, _EMOJI_ORANGE, _EMOJI_RED, _EMOJI_BLUE, _EMOJI_BLUE, _EMOJI_RED, _EMOJI_ORANGE,
407 _EMOJI_GREEN, _EMOJI_BLUE, _EMOJI_RED, _EMOJI_ORANGE, _EMOJI_GREEN, _EMOJI_BLUE, _EMOJI_RED, _EMOJI_ORANGE, _EMOJI_GREEN, _EMOJI_BLUE,
408 _EMOJI_PURPLE, _EMOJI_BLACK, _EMOJI_BLUE, _EMOJI_GREEN, _EMOJI_BLACK, _EMOJI_BLUE, _EMOJI_ORANGE, _EMOJI_BLACK, _EMOJI_PURPLE, _EMOJI_GREEN,
409 _EMOJI_ORANGE, _EMOJI_BLUE, _EMOJI_BLACK, _EMOJI_GREEN, _EMOJI_RED, _EMOJI_BLUE, _EMOJI_BLUE, _EMOJI_RED, _EMOJI_BLUE, _EMOJI_RED,
410 _EMOJI_BLACK, _EMOJI_PURPLE, _EMOJI_RED, _EMOJI_GREEN, _EMOJI_BLUE, _EMOJI_PURPLE, _EMOJI_BLUE, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK,
411 _EMOJI_GREEN, _EMOJI_PURPLE, _EMOJI_ORANGE, _EMOJI_ORANGE, _EMOJI_RED, _EMOJI_BLUE, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_ORANGE,
412 _EMOJI_BLUE, _EMOJI_PURPLE, _EMOJI_BLACK, _EMOJI_RED, _EMOJI_ORANGE, _EMOJI_BLACK, _EMOJI_RED, _EMOJI_BLACK, _EMOJI_RED, _EMOJI_ORANGE,
413 _EMOJI_RED, _EMOJI_RED, _EMOJI_RED, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_ORANGE, _EMOJI_BLUE, _EMOJI_BLACK, _EMOJI_BLUE, _EMOJI_RED,
414 _EMOJI_BLACK, _EMOJI_RED, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_ORANGE, _EMOJI_ORANGE, _EMOJI_ORANGE, _EMOJI_ORANGE, _EMOJI_BLACK, _EMOJI_BLACK,
415 _EMOJI_ORANGE, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLUE, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_ORANGE,
416 _EMOJI_ORANGE, _EMOJI_BLUE, _EMOJI_GREEN, _EMOJI_BLACK, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI,
417 _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _NOT_EMOJI, _NOT_EMOJI, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _NOT_EMOJI, _NOT_EMOJI,
418 _NOT_EMOJI, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI,
419 _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI,
420 _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _NOT_EMOJI, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_ORANGE, _EMOJI_ORANGE, _EMOJI_BLACK,
421 _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_RED, _EMOJI_RED, _EMOJI_RED, _EMOJI_RED, _EMOJI_RED, _EMOJI_RED, _EMOJI_BLUE, _EMOJI_RED,
422 _EMOJI_RED, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK,
423 _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_RED, _EMOJI_RED, _EMOJI_RED, _EMOJI_RED, _EMOJI_PURPLE, _EMOJI_RED,
424 _EMOJI_BLUE, _EMOJI_GREEN, _EMOJI_BLUE, _EMOJI_RED, _EMOJI_RED, _EMOJI_RED, _EMOJI_PURPLE, _EMOJI_RED, _EMOJI_ORANGE, _EMOJI_ORANGE,
425 _EMOJI_BLACK, _EMOJI_RED, _EMOJI_BLACK, _EMOJI_RED, _EMOJI_BLUE, _EMOJI_BLUE, _EMOJI_RED, _EMOJI_PURPLE, _EMOJI_RED, _EMOJI_RED,
426 _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_RED, _EMOJI_ORANGE, _EMOJI_ORANGE, _EMOJI_BLUE, _EMOJI_BLACK,
427 _EMOJI_RED, _EMOJI_DARK_BLUE, _EMOJI_BLUE, _EMOJI_ORANGE, _EMOJI_BROWN, _EMOJI_BROWN, _EMOJI_BLACK, _EMOJI_RED, _EMOJI_BLACK, _EMOJI_GREEN,
428 _EMOJI_ORANGE, _EMOJI_PURPLE, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_GREEN, _EMOJI_BLACK, _EMOJI_GREEN, _EMOJI_PURPLE, _EMOJI_BLUE, _EMOJI_BLUE,
429 _EMOJI_RED, _EMOJI_DEEP_PURPLE, _EMOJI_PURPLE, _EMOJI_ORANGE, _EMOJI_RED, _EMOJI_PURPLE, _EMOJI_PURPLE, _EMOJI_DARK_BLUE, _EMOJI_ORANGE, _EMOJI_BLUE,
430 _EMOJI_BLUE, _EMOJI_RED, _EMOJI_BLUE, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_RED, _EMOJI_GREEN, _EMOJI_BLACK, _EMOJI_ORANGE,
431 _EMOJI_RED, _EMOJI_BLUE, _EMOJI_RED, _EMOJI_RED, _EMOJI_BLACK, _EMOJI_BLACK, _EMOJI_GREEN, _EMOJI_BLUE, _EMOJI_BLUE, _EMOJI_GREEN,
432 _EMOJI_RED, _EMOJI_RED, _EMOJI_ORANGE, _EMOJI_RED, _EMOJI_GREEN, _EMOJI_RED, _EMOJI_PURPLE, _EMOJI_BLACK, _EMOJI_RED, _EMOJI_BROWN,
433 _EMOJI_ORANGE, _EMOJI_BROWN, _EMOJI_BROWN, _EMOJI_ORANGE, _EMOJI_DARK_BLUE, _EMOJI_BLUE, _EMOJI_ORANGE, _EMOJI_ORANGE, _EMOJI_BROWN, _EMOJI_ORANGE,
434 _EMOJI_DEEP_PURPLE, _EMOJI_DEEP_PURPLE
437 if (unicode >= _MIN_EMOJI_UNICODE && unicode <= _MAX_EMOJI_UNICODE)
439 if (_emojiTable[unicode - _MIN_EMOJI_UNICODE] != _NOT_EMOJI)
441 fgColor = _emojiTable[unicode - _MIN_EMOJI_UNICODE];
452 namespace Tizen { namespace Graphics
458 //__fallbackFontMap.Construct(1, 0, _fontHashCodeProvider, _fontComparer);
461 _Font::_Font(const _Font& obj)
463 this->__fontAttrib = obj.__fontAttrib;
464 this->__sharedFont = obj.__sharedFont;
474 _Font::Construct(int style, int pcSize)
476 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
478 // use default system font
479 _FontRsrcManager::SharedFontResource out;
480 result r = mgr.GetFont(style, pcSize, out);
481 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get system default font", GetErrorMessage(r));
485 __UpdateFontAttribute(style, pcSize);
491 _Font::Construct(const Tizen::Base::String& fontName, int style, int pcSize, bool isPathEnabled)
493 result r = E_SUCCESS;
495 if (fontName.Compare(fontName, "TizenSans") == 0)
497 r = Construct(style,pcSize);
499 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get system font", GetErrorMessage(r));
504 bool systemFont = false;
505 String appFontPath = L"";
507 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
508 _FontRsrcManager::SharedFontResource out;
510 if (!Tizen::App::_AppInfo::IsOspCompat())
512 appFontPath = mgr.FindAppFontName(fontName);
515 // check if user want to use a app font
516 if (!appFontPath.IsEmpty())
518 r = mgr.GetFont(appFontPath, style, pcSize, out);
519 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get app font", GetErrorMessage(r));
523 IList* pList = GetSystemFontListN();
528 for (idx = 0; idx < pList->GetCount(); idx++)
530 String* pName = static_cast <String*>(pList->GetAt(idx));
537 if (*pName == fontName)
544 pList->RemoveAll(true);
550 r = mgr.GetSystemFont(fontName, style, pcSize, out);
551 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get system font", GetErrorMessage(r));
553 else if (isPathEnabled)
555 r = mgr.GetFont(fontName, style, pcSize, out);
556 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get font", GetErrorMessage(r));
562 __UpdateFontAttribute(style, pcSize);
568 _Font::Construct(const Tizen::Base::ByteBuffer& fontData, int style, int pcSize)
570 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
572 const byte* pBuffer = fontData.GetPointer();
573 int buffSize = fontData.GetLimit();
575 _FontRsrcManager::SharedFontResource out;
576 result r = mgr.GetFont(pBuffer, buffSize, style, pcSize, out);
577 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get system font", GetErrorMessage(r));
581 __UpdateFontAttribute(style, pcSize);
587 _Font::IsConstructed(void) const
589 return (__sharedFont.get() != null);
593 _Font::GetMaxHeight(void) const
595 IF_NOT_INITIALIZED(return -1);
597 return __fontAttrib.maxHeight;
601 _Font::GetMaxWidth(void) const
603 IF_NOT_INITIALIZED(return -1);
605 return __fontAttrib.maxWidth;
609 _Font::GetAscender(void) const
611 IF_NOT_INITIALIZED(return -1);
613 return __fontAttrib.ascender;
617 _Font::GetDescender(void) const
619 IF_NOT_INITIALIZED(return -1);
621 return __fontAttrib.descender;
625 _Font::GetLeftBear(wchar_t character, int& leftBear) const
627 IF_NOT_INITIALIZED(return E_OPERATION_FAILED);
631 _IFont::Glyph* pFontGlyphData = null;
632 LOAD_GLYPH_DATA_CONST(character, pFontGlyphData, E_SYSTEM);
634 // left bear is Glyph::xOffset, set it
635 leftBear = pFontGlyphData->xOffset;
637 UNLOAD_GLYPH_DATA_CONST(pFontGlyphData);
643 _Font::GetRightBear(wchar_t character, int& rightBear) const
645 IF_NOT_INITIALIZED(return E_OPERATION_FAILED);
649 _IFont::Glyph* pFontGlyphData = null;
650 LOAD_GLYPH_DATA_CONST(character, pFontGlyphData, E_SYSTEM);
652 // right bear is Glyph::xOffset + GlyphBitmap::width, set it
653 rightBear = pFontGlyphData->xOffset + pFontGlyphData->image.width;
655 UNLOAD_GLYPH_DATA_CONST(pFontGlyphData);
661 _Font::GetTextExtent(const Tizen::Base::String& text, int length, Dimension& pcDim) const
665 int x2 = -0x7FFFFFFF;
666 int y2 = -0x7FFFFFFF;
677 wchar_t leftChar = 0;
679 _IFont::Glyph* pFontGlyphData = 0;
681 IF_NOT_INITIALIZED(return E_OPERATION_FAILED);
683 _Font* pThis = const_cast <_Font*>(this);
685 const wchar_t* pText = text.GetPointer();
686 SysTryCatch(NID_GRP, pText, pcDim.SetSize(0, 0), E_SYSTEM, "[E_SYSTEM] Failed to get string pointer");
688 APPLY_ATTRIBUTE(E_SYSTEM);
691 _IFont::Property prop;
692 GET_FONT_PROPERTY(prop, E_SYSTEM);
694 if (__fontAttrib.style & FONT_STYLE_ITALIC)
696 italicSpace = (prop.ascender * 2) >> 4;
700 if (__fontAttrib.style & FONT_STYLE_BOLD)
703 pThis->GetAttrib(attr);
704 boldSpace = (attr.boldWeight + 32) >> 6;
707 while (*pText && --length >= 0)
709 _IFont* pFont = pThis->__GetFont(*pText);
711 if (pFont != __pNativeFont)
713 _IFont::Attrib fontAttrib;
714 bool rtn = pFont->GetAttrib(fontAttrib);
716 fontAttrib.size = __fontAttrib.size;
717 fontAttrib.style = _IFont::STYLE_NONE;
718 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
719 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
720 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
721 rtn = pFont->SetAttrib(fontAttrib);
726 if (pFont->GetKerning(leftChar, *pText, xVec, yVec))
732 if (pFont->LoadGlyph(*pText++, &pFontGlyphData))
734 int glyphBoundX1 = curX;
735 int glyphBoundY1 = curY - (pFontGlyphData->yOffset >> 10);
736 int glyphBoundX2 = glyphBoundX1 + (pFontGlyphData->xOffset >> 10) + pFontGlyphData->image.width;
737 int glyphBoundY2 = glyphBoundY1 + pFontGlyphData->image.height;
739 #ifdef SYNCHRONIZATION_2_0
740 // adjusting x bounds for synchronizing this operation with 2.0
743 glyphBoundX2 = glyphBoundX1 + (pFontGlyphData->xAdvance >> 10) + italicSpace + boldSpace;
745 #endif // 2_0_SYNCHROMIZATION
747 _ExpandBounds(glyphBoundX1, glyphBoundY1, x1, y1, x2, y2);
748 _ExpandBounds(glyphBoundX2, glyphBoundY1, x1, y1, x2, y2);
749 _ExpandBounds(glyphBoundX1, glyphBoundY2, x1, y1, x2, y2);
750 _ExpandBounds(glyphBoundX2, glyphBoundY2, x1, y1, x2, y2);
752 #ifdef SYNCHRONIZATION_2_0
753 curX += (pFontGlyphData->xAdvance >> 10) + __fontAttrib.charSpace + italicSpace + boldSpace;
755 curX += (pFontGlyphData->xAdvance >> 10) + __fontAttrib.charSpace + boldSpace;
757 curY += (pFontGlyphData->yAdvance >> 10);
759 leftChar = *(pText - 1);
761 pFont->UnloadGlyph(&pFontGlyphData);
765 SysTryCatch(NID_GRP, x1 <= x2 && y1 <= y2, pcDim.SetSize(0, 0), E_SYSTEM, "[E_SYSTEM] Failed to calculate text extent");
767 pcDim.width = x2 - x1;
768 #ifdef SYNCHRONIZATION_2_0
769 pcDim.height = CONVERT_26_6_FIXED_POINT_TO_INTEGER(__fontAttrib.size);
771 pcDim.height = y2 - y1;
772 #endif // 2_0_SYNCHROMIZATION
781 _Font::IsBold(void) const
783 IF_NOT_INITIALIZED(return false);
785 return ((__fontAttrib.style & FONT_STYLE_BOLD) ? true : false);
789 _Font::IsItalic(void) const
791 IF_NOT_INITIALIZED(return false);
793 return ((__fontAttrib.style & FONT_STYLE_ITALIC) ? true : false);
797 _Font::IsPlain(void) const
799 IF_NOT_INITIALIZED(return false);
801 return ((__fontAttrib.style & FONT_STYLE_PLAIN) ? true : false);
805 _Font::IsStrikeOut(void) const
807 IF_NOT_INITIALIZED(return false);
809 return __fontAttrib.strikeout;
813 _Font::IsUnderlined(void) const
815 IF_NOT_INITIALIZED(return false);
817 return __fontAttrib.underline;
821 _Font::IsEmoji(void) const
823 IF_NOT_INITIALIZED(return false);
825 return (this->GetFaceName() == L"keitaiemoji");
829 _Font::GetSize(void) const
831 IF_NOT_INITIALIZED(return -1);
833 return CONVERT_26_6_FIXED_POINT_TO_INTEGER(__fontAttrib.size);
837 _Font::SetStrikeOut(bool strikeout)
839 IF_NOT_INITIALIZED(return);
841 __fontAttrib.strikeout = strikeout;
845 _Font::SetUnderline(bool underline)
847 IF_NOT_INITIALIZED(return);
849 __fontAttrib.underline = underline;
853 _Font::SetCharSpace(int pc_space)
855 IF_NOT_INITIALIZED(return);
857 __fontAttrib.charSpace = pc_space;
861 _Font::GetCharSpace(void) const
863 IF_NOT_INITIALIZED(return -1);
865 return __fontAttrib.charSpace;
869 _Font::GetLineThickness(void) const
871 IF_NOT_INITIALIZED(return -1);
873 return __fontAttrib.lineThickness;
877 _Font::GetFaceName(void) const
879 IF_NOT_INITIALIZED(return String());
881 _IFont::Property prop;
882 GET_FONT_PROPERTY(prop, String());
884 return ((prop.pFamilyName) ? String(prop.pFamilyName) : String());
887 Tizen::Base::Collection::IList*
888 _Font::GetSystemFontListN(void)
890 std::auto_ptr<ArrayList> pList(new (std::nothrow) Tizen::Base::Collection::ArrayList);
891 SysTryReturn(NID_GRP, pList.get(), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Fails to allocate memory");
893 result r = _GetSystemFontList(*pList);
894 SysTryReturn(NID_GRP, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
896 return pList.release();
901 _Font::GetFaceName(const Tizen::Base::String& filePath)
903 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
904 _FontRsrcManager::SharedFontResource out;
907 result r = mgr.GetTempFont(filePath, FONT_STYLE_PLAIN, _SYSTEM_DEFAULT_FONT_SIZE, out);
908 SysTryReturn(NID_GRP, r == E_SUCCESS, faceName, r, "[%s] Failed to get font", GetErrorMessage(r));
912 _IFont* pTempFont = out.get();
914 _IFont::Property prop;
915 pTempFont->GetFontProperty(prop);
916 faceName = String(prop.pFamilyName);
923 _Font::GetNativeFont(void) const
925 IF_NOT_INITIALIZED(return null);
927 return __pNativeFont;
933 // if it's not initialized, return null.
934 IF_NOT_INITIALIZED(return null);
937 _Font* pNativeFont = new (std::nothrow) _Font(*this);
938 SysTryReturn(NID_GRP, pNativeFont, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocated memory");
945 _Font::ApplyAttribute()
947 IF_NOT_INITIALIZED(return false);
949 _IFont::Attrib fontAttrib;
950 bool rtn = __pNativeFont->GetAttrib(fontAttrib);
951 SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to get font attribute");
953 fontAttrib.size = __fontAttrib.size;
954 fontAttrib.style = _IFont::STYLE_NONE;
955 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
956 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
957 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
958 rtn = __pNativeFont->SetAttrib(fontAttrib);
959 SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to set font attribute");
966 _Font::GetTextExtent(int width, const Tizen::Base::String& text, int startIndex, int length, bool outline, int& count, Dimension& pcDim) const
968 int preX1 = 0x7FFFFFFF;
969 int preY1 = 0x7FFFFFFF;
970 int preX2 = -0x7FFFFFFF;
971 int preY2 = -0x7FFFFFFF;
975 int x2 = -0x7FFFFFFF;
976 int y2 = -0x7FFFFFFF;
988 wchar_t leftChar = 0;
990 _IFont::Glyph* pFontGlyphData = 0;
992 IF_NOT_INITIALIZED(return E_SYSTEM);
1001 _Font* pThis = const_cast <_Font*>(this);
1003 const wchar_t* pText = text.GetPointer() + startIndex;
1004 SysTryCatch(NID_GRP, pText, pcDim.SetSize(0, 0), E_SYSTEM, "[E_SYSTEM] Failed to get string pointer");
1006 APPLY_ATTRIBUTE(E_SYSTEM);
1009 _IFont::Property prop;
1010 GET_FONT_PROPERTY(prop, E_SYSTEM);
1012 if (__fontAttrib.style & FONT_STYLE_ITALIC)
1014 italicSpace = (prop.ascender * 2) >> 4;
1018 if (__fontAttrib.style & FONT_STYLE_BOLD)
1020 _IFont::Attrib attr;
1021 pThis->GetAttrib(attr);
1022 boldSpace = (attr.boldWeight + 32) >> 6;
1025 while (*pText && --length >= 0)
1027 // getting proper _Font instance for the specified text
1028 _IFont* pFont = pThis->__GetFont(*pText);
1030 if (pFont != __pNativeFont)
1032 _IFont::Attrib fontAttrib;
1033 bool rtn = pFont->GetAttrib(fontAttrib);
1034 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to get font attribute");
1036 fontAttrib.size = __fontAttrib.size;
1037 fontAttrib.style = _IFont::STYLE_NONE;
1038 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
1039 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
1040 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
1041 rtn = pFont->SetAttrib(fontAttrib);
1042 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to set font attribute");
1047 if (pFont->GetKerning(leftChar, *pText, xVec, yVec))
1053 if (pFont->LoadGlyph(*pText++, &pFontGlyphData))
1055 int glyphBoundX1 = curX;
1056 int glyphBoundY1 = curY - (pFontGlyphData->yOffset >> 10);
1057 int glyphBoundX2 = glyphBoundX1 +
1058 ((pFontGlyphData->image.width <= 0) ? (pFontGlyphData->xAdvance >>
1059 10) : ((pFontGlyphData->xOffset >>
1060 10) + pFontGlyphData->image.width));
1061 int glyphBoundY2 = glyphBoundY1 + pFontGlyphData->image.height;
1063 #ifdef SYNCHRONIZATION_2_0
1064 // adjusting x2 bounds for synchronizing fuctionality with 2.0
1065 glyphBoundX2 = glyphBoundX1 + (pFontGlyphData->xAdvance >> 10) + italicSpace + boldSpace;
1077 _ExpandBounds(glyphBoundX1, glyphBoundY1, x1, y1, x2, y2);
1078 _ExpandBounds(glyphBoundX2, glyphBoundY1, x1, y1, x2, y2);
1079 _ExpandBounds(glyphBoundX1, glyphBoundY2, x1, y1, x2, y2);
1080 _ExpandBounds(glyphBoundX2, glyphBoundY2, x1, y1, x2, y2);
1082 #ifdef SYNCHRONIZATION_2_0
1083 curX += (pFontGlyphData->xAdvance >> 10) + __fontAttrib.charSpace + italicSpace + boldSpace;
1085 curX += (pFontGlyphData->xAdvance >> 10) + __fontAttrib.charSpace + boldSpace;
1087 curY += (pFontGlyphData->yAdvance >> 10);
1089 pFont->UnloadGlyph(&pFontGlyphData);
1091 // check end condition
1092 // TODO, shkim, BIDI need to be cared
1093 if ((x2 - x1) > width)
1104 leftChar = *(pText - 1);
1108 if (characters == 0)
1110 pcDim.SetSize(0, 0);
1115 SysTryCatch(NID_GRP, preX1 <= preX2 && preY1 <= preY2, pcDim.SetSize(0, 0); count = 0, E_SYSTEM, "[E_SYSTEM] Failed to calculate text extent");
1118 pcDim.width = preX2 - preX1;
1119 #ifdef SYNCHRONIZATION_2_0
1120 pcDim.height = CONVERT_26_6_FIXED_POINT_TO_INTEGER(__fontAttrib.size);
1122 pcDim.height = preY2 - preY1;
1123 #endif // SYNCHRONIZATION_2_0
1132 _Font::GetTextExtent(int width, const Tizen::Base::String& text, int startIndex, int length, bool outline, const Tizen::Base::String& delimiter, int& count, Dimension& dim) const
1134 IF_NOT_INITIALIZED(return E_OPERATION_FAILED);
1136 SysTryReturn(NID_GRP, startIndex >= 0 && length >= 0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
1138 const wchar_t* pBaseStringBegin = text.GetPointer();
1139 const wchar_t* pBaseStringEnd = pBaseStringBegin + text.GetLength();
1141 const wchar_t* pTextBegin = pBaseStringBegin + startIndex;
1142 const wchar_t* pTextEnd = pTextBegin + length;
1144 pTextEnd = (pTextEnd < pBaseStringEnd) ? pTextEnd : pBaseStringEnd;
1146 const wchar_t* pText = pTextBegin;
1148 while (pText < pTextEnd)
1150 if (*pText == 0x0D || *pText == 0x0A)
1159 return this->GetTextExtent(width, text, startIndex, pTextEnd - pTextBegin, outline, count, dim);
1163 _Font::SetSize(int pcSize)
1165 IF_NOT_INITIALIZED(return E_OPERATION_FAILED);
1167 __UpdateFontAttribute(__fontAttrib.style, pcSize);
1173 _Font::SetStyle(int style)
1175 IF_NOT_INITIALIZED(return E_OPERATION_FAILED);
1177 __fontAttrib.style = style;
1183 _Font::GetStyle(void) const
1185 IF_NOT_INITIALIZED(return FONT_STYLE_PLAIN);
1187 return __fontAttrib.style;
1191 _Font::GetLeading(void) const
1193 IF_NOT_INITIALIZED(return -1);
1195 return __fontAttrib.maxHeight;
1199 _Font::__DrawText(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length)
1201 SysTryReturnResult(NID_GRP, canvas.__pScratchPad != null, E_INVALID_ARG, "A canvas is invalid");
1203 const wchar_t* pText = text.GetPointer() + startIndex;
1205 bool rtn = this->ApplyAttribute();
1206 SysTryReturn(NID_GRP, rtn, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fails to apply font attribute.");
1208 _Util::ScratchPad <SystemPixel>& scratchPad = *canvas.__pScratchPad;
1209 scratchPad.RegisterFillRect(_RasterOp::FnFillRectFont32Bit);
1211 Rectangle clipBounds;
1212 canvas.__GetClipBounds(clipBounds);
1214 int xDest = point.x;
1215 int yDest = point.y;
1216 int startX = point.x;
1218 int italicSpace = 0;
1220 int clipX1 = clipBounds.x;
1221 int clipY1 = clipBounds.y;
1222 int clipX2 = clipX1 + clipBounds.width;
1223 int clipY2 = clipY1 + clipBounds.height;
1227 wchar_t leftChar = 0;
1228 _IFont::Glyph* pFontGlyphData = 0;
1230 // need to revise y value, because _IFont is based on the baseline
1232 _IFont::Property prop;
1233 bool rtn = this->GetFontProperty(prop);
1234 SysTryReturn(NID_GRP, rtn, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to get font property.");
1236 if (canvas.__textOrigin == TEXT_ORIGIN_LEFT_TOP)
1238 yDest += prop.maxHeight + prop.descender;
1241 charHeight = prop.ascender - prop.descender;
1243 if (this->GetStyle() & FONT_STYLE_ITALIC)
1245 italicSpace = (prop.ascender * 2) >> 4;
1249 if (this->GetStyle() & FONT_STYLE_BOLD)
1251 _IFont::Attrib attr;
1252 this->GetAttrib(attr);
1253 boldSpace = (attr.boldWeight + 32) >> 6;
1256 unsigned long canvasFgColor = canvas.__fgColor;
1258 GUnicodeScript script = g_unichar_get_script(*pText);
1259 // need to check if (script < 0 || script >= _sampleLanguageCount) ?
1261 // Temporary code for testing Arabic
1262 if (script == G_UNICODE_SCRIPT_ARABIC)
1264 _FontBidiProps bidiProps(pText, length);
1266 _IFont* pFont = this->__GetFont(*pText);
1273 Tizen::Base::Collection::ArrayListT<_IFont::Glyph *> glyphList;
1275 pFont->GetGlyphList(_Util::String(text.GetPointer(), text.GetLength(), startIndex, length), glyphList, bidiProps.isRtl, script);
1277 int count = glyphList.GetCount();
1279 for (int i = 0; i < count; i++)
1281 typedef unsigned long TPixel;
1282 _IFont::Glyph *pGlyph = 0;
1284 TPixel srcR, srcG, srcB, srcA;
1285 TPixel dstR, dstG, dstB, dstA;
1287 srcA = (canvasFgColor >> 24) & 0xFF;
1288 srcA += (srcA >> 7);
1289 srcR = (canvasFgColor >> 16) & 0xFF;
1290 srcG = (canvasFgColor >> 8) & 0xFF;
1291 srcB = (canvasFgColor) & 0xFF;
1293 SystemPixel* pBufferStartAddr = null;
1296 scratchPad.GetBuffer(pBufferStartAddr, bufferPitch);
1298 glyphList.GetAt(i, pGlyph);
1300 for (int h = 0; h < pGlyph->image.height; h++)
1302 int y = yDest - pGlyph->yOffset + h;
1309 if (y >= scratchPad.GetHeight())
1314 TPixel* pDest32 = pBufferStartAddr + y * bufferPitch + xDest + pGlyph->xOffset;
1316 for (int w = 0; w < pGlyph->image.width; w++)
1318 int x = xDest + pGlyph->xOffset + w;
1326 if (x >= scratchPad.GetWidth())
1331 unsigned long alpha = (unsigned long) (pGlyph->image.pBitmap[h * pGlyph->image.bytesPerLine + w]);
1335 // equivalent to scratchPad.FillRect(x, y, 1, 1, fgColor, alpha);
1336 alpha = (alpha * srcA) >> 8;
1337 alpha += (alpha >> 7);
1339 dstA = (*pDest32 >> 24) & 0xFF;
1340 dstR = (*pDest32 >> 16) & 0xFF;
1341 dstG = (*pDest32 >> 8) & 0xFF;
1342 dstB = (*pDest32) & 0xFF;
1344 dstA = BLEND_ALPHA_COMPONEMT(alpha, dstA);
1345 dstR = (dstR + (((srcR - dstR) * alpha) >> 8)) & 0xFF;
1346 dstG = (dstG + (((srcG - dstG) * alpha) >> 8)) & 0xFF;
1347 dstB = (dstB + (((srcB - dstB) * alpha) >> 8)) & 0xFF;
1349 *pDest32 = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB;
1356 xDest += (pGlyph->xAdvance >> 10);
1357 yDest += (pGlyph->yAdvance >> 10);
1360 scratchPad.RegisterFillRect(null);
1362 IEnumeratorT<_IFont::Glyph*>* pEnum = glyphList.GetEnumeratorN();
1366 while (pEnum->MoveNext() == E_SUCCESS)
1368 _IFont::Glyph* pGlyph;
1370 pEnum->GetCurrent(pGlyph);
1379 while (*pText && --length >= 0)
1381 // find out proper native font
1382 _IFont* pFont = this->__GetFont(*pText);
1389 if (pFont != __pNativeFont)
1391 _IFont::Attrib fontAttrib;
1392 bool rtn = pFont->GetAttrib(fontAttrib);
1393 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to get font attribute");
1395 fontAttrib.size = __fontAttrib.size;
1396 fontAttrib.style = _IFont::STYLE_NONE;
1397 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_BOLD) ? _IFont::STYLE_BOLD : 0;
1398 fontAttrib.style |= (__fontAttrib.style & FONT_STYLE_ITALIC) ? _IFont::STYLE_ITALIC : 0;
1399 fontAttrib.style |= (__fontAttrib.underline) ? _IFont::STYLE_UNDERLINE : 0;
1400 rtn = pFont->SetAttrib(fontAttrib);
1401 //SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to set font attribute");
1404 _IFont::Property prop;
1405 pFont->GetFontProperty(prop);
1407 unsigned long fgColor = (canvas.__applyEmoji && (String(prop.pFamilyName) == L"keitaiemoji")) ? GetPredefinedColor(*pText, canvasFgColor) : canvasFgColor;
1411 if (pFont->GetKerning(leftChar, *pText, xVec, yVec))
1417 bool rtn = pFont->LoadGlyph(*pText++, &pFontGlyphData);
1424 typedef unsigned long TPixel;
1426 TPixel srcA = (fgColor >> 24) & 0xFF;
1427 srcA += (srcA >> 7);
1429 TPixel srcR = (fgColor >> 16) & 0xFF;
1430 TPixel srcG = (fgColor >> 8) & 0xFF;
1431 TPixel srcB = (fgColor) & 0xFF;
1433 SystemPixel* pBufferStartAddr = null;
1434 int bufferPitch = 0;
1436 scratchPad.GetBuffer(pBufferStartAddr, bufferPitch);
1438 for (int h = 0; h < pFontGlyphData->image.height; h++)
1440 int y = yDest - (pFontGlyphData->yOffset >> 10) + h;
1452 TPixel* pDest32 = pBufferStartAddr + y * bufferPitch + xDest + (pFontGlyphData->xOffset >> 10);
1454 for (int w = 0; w < pFontGlyphData->image.width; w++)
1456 int x = xDest + (pFontGlyphData->xOffset >> 10) + w;
1469 unsigned long alpha = (unsigned long) (pFontGlyphData->image.pBitmap[h * pFontGlyphData->image.bytesPerLine + w]);
1473 // equivalent to scratchPad.FillRect(x, y, 1, 1, fgColor, alpha);
1474 alpha = (alpha * srcA) >> 8;
1475 alpha += (alpha >> 7);
1477 TPixel dstA = (*pDest32 >> 24) & 0xFF;
1478 TPixel dstR = (*pDest32 >> 16) & 0xFF;
1479 TPixel dstG = (*pDest32 >> 8) & 0xFF;
1480 TPixel dstB = (*pDest32) & 0xFF;
1482 dstA = BLEND_ALPHA_COMPONEMT(alpha, dstA);
1483 dstR = (dstR + (((srcR - dstR) * alpha) >> 8)) & 0xFF;
1484 dstG = (dstG + (((srcG - dstG) * alpha) >> 8)) & 0xFF;
1485 dstB = (dstB + (((srcB - dstB) * alpha) >> 8)) & 0xFF;
1487 *pDest32 = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB;
1494 xDest += (pFontGlyphData->xAdvance >> 10) + __fontAttrib.charSpace + italicSpace + boldSpace;
1495 yDest += (pFontGlyphData->yAdvance >> 10);
1497 leftChar = *(pText - 1);
1499 pFont->UnloadGlyph(&pFontGlyphData);
1503 if (this->IsUnderlined() || this->IsStrikeOut())
1505 int y = point.y + charHeight - 1;
1506 int thick = this->GetLineThickness();
1508 xDest -= this->GetCharSpace();
1510 if (this->IsUnderlined())
1512 canvas.FillRectangle(canvasFgColor, Rectangle(startX, y - thick, xDest - startX, thick));
1515 if (this->IsStrikeOut())
1517 y -= charHeight / 2;
1518 canvas.FillRectangle(canvasFgColor, Rectangle(startX, y - thick, xDest - startX, thick));
1522 scratchPad.RegisterFillRect(null);
1528 #undef BLEND_ALPHA_COMPONEMT
1531 _Font::__DrawText(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length, const Color& outlineColor)
1533 unsigned long textColor = canvas.__fgColor;
1534 bool applyEmoji = canvas.__applyEmoji;
1536 //sunmi557.shin: draw border of font
1537 canvas.__fgColor = outlineColor.GetRGB32();
1538 canvas.__applyEmoji = false;
1540 this->__DrawText(canvas, Point(point.x - 1, point.y), text, startIndex, length);
1541 this->__DrawText(canvas, Point(point.x + 1, point.y), text, startIndex, length);
1542 this->__DrawText(canvas, Point(point.x, point.y - 1), text, startIndex, length);
1543 this->__DrawText(canvas, Point(point.x, point.y + 1), text, startIndex, length);
1545 //sunmi557.shin: draw original shape of font
1546 canvas.__applyEmoji = applyEmoji;
1547 canvas.__fgColor = textColor;
1549 this->__DrawText(canvas, point, text, startIndex, length);
1555 _Font::SetAttrib(const _IFont::Attrib& fontAttrib)
1557 IF_NOT_INITIALIZED(return false);
1559 return __pNativeFont->SetAttrib(fontAttrib);
1563 _Font::GetAttrib(_IFont::Attrib& fontAttrib) const
1565 IF_NOT_INITIALIZED(return false);
1567 return __pNativeFont->GetAttrib(fontAttrib);
1571 _Font::GetKerning(unsigned long character1, unsigned long character2, long& xVector, long& yVector) const
1573 IF_NOT_INITIALIZED(return false);
1575 return __pNativeFont->GetKerning(character1, character2, xVector, yVector);
1579 _Font::GetFontProperty(_IFont::Property& property) const
1581 IF_NOT_INITIALIZED(return false);
1583 return __pNativeFont->GetFontProperty(property);
1587 _Font::LoadGlyph(unsigned long character, _IFont::Glyph** ppFontGlyphData)
1589 IF_NOT_INITIALIZED(return false);
1591 // note! we assume that the font attribute has been already applied on _IFont
1594 // if not, loading glyph (character/size/style) and caching it
1595 rtn = __pNativeFont->LoadGlyph(character, ppFontGlyphData);
1596 SysTryReturn(NID_GRP, rtn, false, E_SYSTEM, "[E_SYSTEM] Failed to load glyph data");
1598 // return cached glyph
1603 _Font::UnloadGlyph(_IFont::Glyph** ppFontGlyphData)
1605 IF_NOT_INITIALIZED(return false);
1607 return __pNativeFont->UnloadGlyph(ppFontGlyphData);
1611 _Font::CheckGlyph(unsigned long character)
1613 IF_NOT_INITIALIZED(return false);
1615 return __pNativeFont->CheckGlyph(character);
1619 _Font::__UpdateFontAttribute(int style, int pcSize)
1621 IF_NOT_INITIALIZED(return);
1623 __fontAttrib.style = style;
1624 __fontAttrib.size = pcSize;
1625 __fontAttrib.lineThickness = ((CONVERT_26_6_FIXED_POINT_TO_INTEGER(pcSize) < 24) ? 1 : ((CONVERT_26_6_FIXED_POINT_TO_INTEGER(pcSize) < 48) ? 2 : 3));
1627 _IFont::Property prop;
1628 bool getProperty = false;
1630 if (this->ApplyAttribute())
1632 getProperty = __pNativeFont->GetFontProperty(prop);
1637 __fontAttrib.maxWidth = prop.maxWidth;
1638 __fontAttrib.maxHeight = prop.maxHeight;
1639 __fontAttrib.ascender = prop.ascender;
1640 __fontAttrib.descender = prop.descender;
1644 // if failed to get property above, each property should be remained as default: -1
1645 SysLog(NID_GRP, "[] Failed to get font attribute from native font");
1647 __fontAttrib.maxWidth = -1;
1648 __fontAttrib.maxHeight = -1;
1649 __fontAttrib.ascender = -1;
1650 __fontAttrib.descender = -1;
1655 _Font::__DrawTextLastFallback(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length)
1661 _Font::__DrawTextDefault(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length)
1663 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
1664 result r = mgr.GetDefaultSystemFont().__DrawText(canvas, point, text, startIndex, length);
1665 SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Failed to draw default system font", GetErrorMessage(r));
1670 _Font::__DrawTextLastFallback(canvas, point, text, startIndex, length);
1675 _Font::__DrawTextDefault(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length, const Color& outlineColor)
1677 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
1678 result r = mgr.GetDefaultSystemFont().__DrawText(canvas, point, text, startIndex, length, outlineColor);
1679 SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Failed to draw default system font", GetErrorMessage(r));
1684 _Font::__DrawTextLastFallback(canvas, point, text, startIndex, length);
1690 _Font::DrawText(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length)
1692 if (canvas.__pPriorityFont)
1694 return canvas.__pPriorityFont->__DrawText(canvas, point, text, startIndex, length);
1696 else if (canvas.__pFont)
1698 return canvas.__pFont->__DrawText(canvas, point, text, startIndex, length);
1702 return _Font::__DrawTextDefault(canvas, point, text, startIndex, length);
1707 _Font::DrawText(_Canvas& canvas, const Point& point, const Tizen::Base::String& text, int startIndex, int length, const Color& outlineColor)
1709 if (canvas.__pPriorityFont)
1711 return canvas.__pPriorityFont->__DrawText(canvas, point, text, startIndex, length, outlineColor);
1713 else if (canvas.__pFont)
1715 return canvas.__pFont->__DrawText(canvas, point, text, startIndex, length, outlineColor);
1719 return _Font::__DrawTextDefault(canvas, point, text, startIndex, length, outlineColor);
1726 _Font::GetInstance(_FontImpl& font)
1728 return (&font != null) ? font._pNativeFont : null;
1732 _Font::GetInstance(const _FontImpl& font)
1734 return (&font != null) ? font._pNativeFont : null;
1738 _Font::__GetFont(wchar_t character)
1740 IF_NOT_INITIALIZED(return null);
1742 //------------------------------------------------------
1744 // 1. check if this font has a requested glyph
1746 //------------------------------------------------------
1747 unsigned long idx = __pNativeFont->CheckGlyph(character);
1751 return __pNativeFont;
1754 //------------------------------------------------------
1756 // 1-2. check if this glyph is in the fallback list.
1758 //------------------------------------------------------
1759 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
1760 Tizen::Base::Collection::HashMapT<String, _FontRsrcManager::SharedFontResource>* fallbackFontMap = __pNativeFont->GetFallbackMap();
1761 std::auto_ptr<IMapEnumeratorT<String, _FontRsrcManager::SharedFontResource> > enumerator(fallbackFontMap->GetMapEnumeratorN());
1763 while (enumerator->MoveNext() == E_SUCCESS)
1765 _FontRsrcManager::SharedFontResource pTempFont;
1767 if (enumerator->GetValue(pTempFont) == E_SUCCESS)
1770 result r = enumerator->GetKey(key);
1774 if (mgr.SearchFont(key))
1776 if (pTempFont.get()->CheckGlyph(character) > 0)
1778 return pTempFont.get();
1783 fallbackFontMap->Remove(key);
1789 //------------------------------------------------------
1791 // 2. Get fallback font list via fontconfig
1793 //------------------------------------------------------
1794 Tizen::Base::Collection::ArrayListT<String> fileList;
1795 bool rtn = __GetFallbackFontFileList(character, fileList);
1798 // if failed find out fallback font,
1799 // just use this instance for drawing something for unknown glyph
1800 return __pNativeFont;
1803 //------------------------------------------------------
1805 // 3. try to find a font having a requested glyph
1807 //------------------------------------------------------
1809 _IFont* pFallbackFont = null;
1811 _FontRsrcManager::SharedFontResource out;
1813 int count = fileList.GetCount();
1814 result r = E_FAILURE;
1816 for (int i = 0; i < count; i++)
1818 fileList.GetAt(i, fontName);
1820 if (fontName.IsEmpty())
1825 r = mgr.GetTempFont(fontName, __fontAttrib.style, __fontAttrib.size, out);
1829 unsigned long idx = out.get()->CheckGlyph(character);
1834 r = fallbackFontMap->Add(fontName, out);
1835 SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
1837 r = mgr.AddFont(fontName, out);
1838 SysTryCatch(NID_GRP, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
1840 pFallbackFont = out.get();
1846 return (pFallbackFont != null) ? pFallbackFont : __pNativeFont;
1849 // if failed find out fallback font,
1850 // just use this instance for drawing something for unknown glyph
1851 return __pNativeFont;
1855 _Font::__GetFallbackFontFileList(wchar_t character, Tizen::Base::Collection::IListT<String>& out)
1857 GUnicodeScript script = g_unichar_get_script(character);
1858 if (script < 0 || script >= _sampleLanguageCount)
1863 _IFont::Property prop;
1864 const char* pFamilyName = null;
1865 GET_FONT_PROPERTY(prop, false);
1867 pFamilyName = prop.pFamilyName;
1869 FcPattern* pPattern = null;
1870 FcFontSet* pSet = null;
1871 FcChar8* pName = null;
1872 FcResult res = FcResultNoMatch;
1873 const char* fcStyle = (__fontAttrib.style & FONT_STYLE_BOLD) ? "Bold" : "Regular";
1875 // initialize fontconfig library
1876 FcBool rtn = FcInit();
1877 SysTryCatch(NID_GRP, rtn, , E_SYSTEM, "[E_SYSTEM] Failed to init fontconfig");
1879 // getting fallback font list
1880 pPattern = FcPatternBuild(NULL, FC_STYLE, FcTypeString, (FcChar8*)fcStyle, NULL);
1881 SysTryCatch(NID_GRP, pPattern, , E_SYSTEM, "[E_SYSTEM] Failed to FcPatternBuild()");
1883 FcPatternAddString(pPattern, FC_FAMILY, (FcChar8*) pFamilyName);
1885 if (strncmp(SAMPLE_LANGUAGE_EMPTY, _SampleLanguages[script], strlen(SAMPLE_LANGUAGE_EMPTY) + 1) != 0)
1887 FcPatternAddString(pPattern, FC_LANG, (FcChar8*)_SampleLanguages[script]);
1890 FcConfigSubstitute(NULL, pPattern, FcMatchPattern);
1891 FcDefaultSubstitute(pPattern);
1894 pSet = FcFontSort(NULL, pPattern, FcTrue, NULL, &res);
1895 SysTryCatch(NID_GRP, pSet, , E_SYSTEM, "[E_SYSTEM] Failed to FcFontSort()");
1899 for (int i = 0; i < pSet->nfont; i++)
1901 if (FcPatternGetString(pSet->fonts[i], FC_FILE, 0, &pName) == FcResultMatch)
1903 out.Add(String((char*)pName));
1908 FcFontSetDestroy(pSet);
1909 FcPatternDestroy(pPattern);
1912 return (out.GetCount() > 0) ? true : false;
1917 FcFontSetDestroy(pSet);
1920 if (pPattern != null)
1922 FcPatternDestroy(pPattern);
1931 _Font::UpdateDefaultFont(const String& key)
1935 SysLog(NID_GRP, "Request to change the default font");
1937 _FontRsrcManager& mgr = _FontRsrcManager::GetInstance();
1939 return mgr.ReloadDefaultSystemFont();
1945 }} // Tizen::Graphics