add patch
[framework/osp/uifw.git] / src / graphics / FGrp_FontImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
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
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0/
10 //
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.
16 //
17
18 /*
19  * @file        FGrp_FontImpl.cpp
20  * @brief       This is the implementation file for _FontImpl class.
21  *
22  */
23
24 #include <new>
25 #include <memory>
26 #include <pthread.h>
27
28 #include <FGrpFont.h>
29 #include <FBaseSysLog.h>
30 #include <FBaseRtMutex.h>
31
32 #include "FGrp_FontImpl.h"
33 #include "FGrp_Font.h"
34 #include "FGrp_ResUtil.h"
35 #include "util/FGrp_Util.h"
36
37
38 using namespace Tizen::Base::Runtime;
39
40 #define IF_NOT_INITIALIZED(code) if (this->_pNativeFont == null || this->_pCoordHolder == null) \
41         { \
42                 code; \
43         }
44 #define IF_NOT_CONSTRUCTED(code) if (this->_pNativeFont == null || (!this->_pNativeFont->IsConstructed())) \
45         { \
46                 code; \
47         }
48 #define IsSucceeded(X) (!IsFailed(X))
49
50
51 #if 1
52 #define CRITICAL_SECTION _MutexGuard __mutexGuard__
53 #else
54 #define CRITICAL_SECTION
55 #endif
56
57
58 namespace Tizen { namespace Graphics
59 {
60
61 class _MutexGuard
62 {
63 public:
64         _MutexGuard()
65         {
66                 Mutex* pMutex = GetMutexInstance();
67                 pMutex->Acquire();
68         }
69
70         ~_MutexGuard()
71         {
72                 Mutex* pMutex = GetMutexInstance();
73                 pMutex->Release();
74         }
75
76 private:
77         static void __InitCreateMutex(void)
78         {
79                 static Mutex mutex;
80                 mutex.Create();
81                 _MutexGuard::pMutexInstance = &mutex;
82         }
83
84         static Mutex* GetMutexInstance(void)
85         {
86                 static pthread_once_t once_block = PTHREAD_ONCE_INIT;
87
88                 if (_MutexGuard::pMutexInstance == null)
89                 {
90                         pthread_once(&once_block, __InitCreateMutex);
91                 }
92
93                 return _MutexGuard::pMutexInstance;
94         }
95
96 public:
97         static Mutex* pMutexInstance;
98 };
99
100 Mutex* _MutexGuard::pMutexInstance = null;
101
102
103 struct _FontCoordHolder
104 {
105         _ResUtil::CoordHolder <int> size;
106         _ResUtil::CoordHolder <int> charSpace;
107         _ResUtil::CoordHolder <float> sizeF;
108         _ResUtil::CoordHolder <float> charSpaceF;
109
110         _FontCoordHolder()
111         {
112                 Reset(-1);
113                 Reset(-1.0f);
114         }
115
116         void Reset(int _size)
117         {
118                 size = _size;
119                 charSpace = 0;
120                 sizeF = static_cast<float>(_size);
121                 charSpaceF = 0.0f;
122         }
123
124         void Reset(float _size)
125         {
126                 size = static_cast<int>(_size);
127                 charSpace = 0;
128                 sizeF = _size;
129                 charSpaceF = 0.0f;
130         }
131 };
132
133
134 _FontImpl::_FontImpl()
135         : _magicKey(0)
136         , _pCoordHolder(new (std::nothrow) _FontCoordHolder)
137         , _pNativeFont(new (std::nothrow) _Font)
138 {
139         if (_pNativeFont == null || _pCoordHolder == null)
140         {
141                 delete _pNativeFont;
142                 delete _pCoordHolder;
143
144                 _pNativeFont = null;
145                 _pCoordHolder = null;
146         }
147
148         _Util::CarveMagicKey(*this, _magicKey);
149 }
150
151 _FontImpl::_FontImpl(const _FontImpl& obj)
152         : _pCoordHolder(new (std::nothrow) _FontCoordHolder)
153         , _pNativeFont(0)
154 {
155         if (_pCoordHolder)
156         {
157                 *_pCoordHolder = *obj._pCoordHolder;
158         }
159
160         _pNativeFont = obj._pNativeFont->CloneN();
161
162         if (_pNativeFont == null || _pCoordHolder == null)
163         {
164                 delete _pNativeFont;
165                 delete _pCoordHolder;
166
167                 _pNativeFont = null;
168                 _pCoordHolder = null;
169         }
170
171         _Util::CarveMagicKey(*this, _magicKey);
172 }
173
174 _FontImpl::~_FontImpl()
175 {
176         if (_pNativeFont)
177         {
178                 delete _pNativeFont;
179                 _pNativeFont = 0;
180         }
181
182         if (_pCoordHolder)
183         {
184                 delete _pCoordHolder;
185                 _pCoordHolder = 0;
186         }
187
188         _Util::EraseMagicKey(*this, _magicKey);
189 }
190
191 result
192 _FontImpl::Construct(int style, int vcSize)
193 {
194         CRITICAL_SECTION;
195         IF_NOT_INITIALIZED(return E_OUT_OF_MEMORY);
196
197         // convert VC -> PC
198         _Util::FixedPoint26_6 pcSize(_ResUtil::ConvertToPhyCoordHeight(static_cast<float>(vcSize)));
199
200         if (vcSize > 0 && pcSize <= 1)
201         {
202                 pcSize = _Util::FixedPoint26_6(1);
203         }
204
205         result r = _pNativeFont->Construct(style, pcSize);
206         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to construct _Font", GetErrorMessage(r));
207
208         _pCoordHolder->Reset(vcSize);
209
210         return E_SUCCESS;
211 }
212
213 result
214 _FontImpl::Construct(const Tizen::Base::String& fontName, int style, int vcSize, bool isPathEnabled)
215 {
216         CRITICAL_SECTION;
217         IF_NOT_INITIALIZED(return E_OUT_OF_MEMORY);
218
219         // convert VC -> PC
220         _Util::FixedPoint26_6 pcSize(_ResUtil::ConvertToPhyCoordHeight(static_cast<float>(vcSize)));
221
222         if (vcSize > 0 && pcSize <= 1)
223         {
224                 pcSize = _Util::FixedPoint26_6(1);
225         }
226
227         result r = _pNativeFont->Construct(fontName, style, pcSize, isPathEnabled);
228         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to construct _Font", GetErrorMessage(r));
229
230         _pCoordHolder->Reset(vcSize);
231
232         return E_SUCCESS;
233 }
234
235 result
236 _FontImpl::Construct(const Tizen::Base::ByteBuffer& fontData, int style, int vcSize)
237 {
238         CRITICAL_SECTION;
239         IF_NOT_INITIALIZED(return E_OUT_OF_MEMORY);
240
241         // convert VC -> PC
242         _Util::FixedPoint26_6 pcSize(_ResUtil::ConvertToPhyCoordHeight(static_cast<float>(vcSize)));
243
244         if (vcSize > 0 && pcSize <= 1)
245         {
246                 pcSize = _Util::FixedPoint26_6(1);
247         }
248
249         result r = _pNativeFont->Construct(fontData, style, pcSize);
250         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to construct _Font", GetErrorMessage(r));
251
252         _pCoordHolder->Reset(vcSize);
253
254         return E_SUCCESS;
255 }
256
257 result
258 _FontImpl::Construct(int style, float vcSize)
259 {
260         CRITICAL_SECTION;
261         IF_NOT_INITIALIZED(return E_OUT_OF_MEMORY);
262
263         // convert VC -> PC
264         _Util::FixedPoint26_6 pcSize(_ResUtil::ConvertToPhyCoordHeight(vcSize));
265
266         if (vcSize > 0.0f && pcSize <= 1.0f)
267         {
268                 pcSize = _Util::FixedPoint26_6(1.0f);
269         }
270
271         result r = _pNativeFont->Construct(style, pcSize);
272         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to construct _Font", GetErrorMessage(r));
273
274         _pCoordHolder->Reset(vcSize);
275
276         return E_SUCCESS;
277 }
278
279 result
280 _FontImpl::Construct(const Tizen::Base::String& fontName, int style, float vcSize, bool isPathEnabled)
281 {
282         CRITICAL_SECTION;
283         IF_NOT_INITIALIZED(return E_OUT_OF_MEMORY);
284
285         // convert VC -> PC
286         _Util::FixedPoint26_6 pcSize(_ResUtil::ConvertToPhyCoordHeight(vcSize));
287
288         if (vcSize > 0.0f && pcSize <= 1.0f)
289         {
290                 pcSize = _Util::FixedPoint26_6(1.0f);
291         }
292
293         result r = _pNativeFont->Construct(fontName, style, pcSize, isPathEnabled);
294         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to construct _Font", GetErrorMessage(r));
295
296         _pCoordHolder->Reset(vcSize);
297
298         return E_SUCCESS;
299 }
300
301 result
302 _FontImpl::Construct(const Tizen::Base::ByteBuffer& fontData, int style, float vcSize)
303 {
304         CRITICAL_SECTION;
305         IF_NOT_INITIALIZED(return E_OUT_OF_MEMORY);
306
307         // convert VC -> PC
308         _Util::FixedPoint26_6 pcSize(_ResUtil::ConvertToPhyCoordHeight(vcSize));
309
310         if (vcSize > 0.0f && pcSize <= 1.0f)
311         {
312                 pcSize = _Util::FixedPoint26_6(1.0f);
313         }
314
315         result r = _pNativeFont->Construct(fontData, style, pcSize);
316         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to construct _Font", GetErrorMessage(r));
317
318         _pCoordHolder->Reset(vcSize);
319
320         return E_SUCCESS;
321 }
322
323 bool
324 _FontImpl::IsConstructed(void) const
325 {
326         CRITICAL_SECTION;
327         IF_NOT_CONSTRUCTED(return false);
328
329         return true;
330 }
331
332 int
333 _FontImpl::GetMaxHeight(void) const
334 {
335         CRITICAL_SECTION;
336         IF_NOT_CONSTRUCTED(return -1);
337
338         int pcMaxHeight = _DoubleToIntForPos(ceil(_pNativeFont->GetMaxHeight().ToDouble()));
339
340         for (int i = pcMaxHeight; i < INT_MAX; i++)
341         {
342                 if (_ResUtil::ConvertToPhyCoord(_ResUtil::ConvertToVirCoordY(i)) >= pcMaxHeight)
343                 {
344                         pcMaxHeight = i;
345                         break;
346                 }
347         }
348
349         int vcMaxHeight = _ResUtil::ConvertToVirCoordY(pcMaxHeight);
350
351         return vcMaxHeight;
352 }
353
354 float
355 _FontImpl::GetMaxHeightF(void) const
356 {
357         CRITICAL_SECTION;
358         IF_NOT_CONSTRUCTED(return -1.0f);
359
360         float pcMaxHeight = float(ceil(_pNativeFont->GetMaxHeight().ToDouble()));
361         float vcMaxHeight = _ResUtil::ConvertToVirCoordY(pcMaxHeight);
362
363         return vcMaxHeight;
364 }
365
366 int
367 _FontImpl::GetMaxWidth(void) const
368 {
369         CRITICAL_SECTION;
370         IF_NOT_CONSTRUCTED(return -1);
371
372         int pcMaxWidth = _pNativeFont->GetMaxWidth().ToInt();
373         int vcMaxWidth = _ResUtil::ConvertToVirCoordX(pcMaxWidth);
374
375         return vcMaxWidth;
376 }
377
378 float
379 _FontImpl::GetMaxWidthF(void) const
380 {
381         CRITICAL_SECTION;
382         IF_NOT_CONSTRUCTED(return -1.0f);
383
384         float pcMaxWidth = _pNativeFont->GetMaxWidth().ToFloat();
385         float vcMaxWidth = _ResUtil::ConvertToVirCoordX(pcMaxWidth);
386
387         return vcMaxWidth;
388 }
389
390 int
391 _FontImpl::GetAscender(void) const
392 {
393         CRITICAL_SECTION;
394         IF_NOT_CONSTRUCTED(return -1);
395
396         int pcAscender = _DoubleToIntForPos(ceil(_pNativeFont->GetAscender().ToDouble()));
397
398         for (int i = pcAscender; i < INT_MAX; i++)
399         {
400                 if (_ResUtil::ConvertToPhyCoord(_ResUtil::ConvertToVirCoordY(i)) >= pcAscender)
401                 {
402                         pcAscender = i;
403                         break;
404                 }
405         }
406
407         int vcAscender = _ResUtil::ConvertToVirCoordY(pcAscender);
408
409         return vcAscender;
410 }
411
412 float
413 _FontImpl::GetAscenderF(void) const
414 {
415         CRITICAL_SECTION;
416         IF_NOT_CONSTRUCTED(return -1.0f);
417
418         float pcAscender = float(ceil(_pNativeFont->GetAscender().ToDouble()));
419         float vcAscender = _ResUtil::ConvertToVirCoordY(pcAscender);
420
421         return vcAscender;
422 }
423
424 int
425 _FontImpl::GetDescender(void) const
426 {
427         CRITICAL_SECTION;
428         IF_NOT_CONSTRUCTED(return -1);
429
430         int pcDescender = _DoubleToIntForPos(ceil(_pNativeFont->GetDescender().ToDouble()));
431
432         if (pcDescender < 0)
433         {
434                 pcDescender *= -1;
435         }
436
437         for (int i = pcDescender; i < INT_MAX; i++)
438         {
439                 if (_ResUtil::ConvertToPhyCoord(_ResUtil::ConvertToVirCoordY(i)) >= pcDescender)
440                 {
441                         pcDescender = i;
442                         break;
443                 }
444         }
445
446         int vcDescender = _ResUtil::ConvertToVirCoordY(pcDescender);
447
448         return vcDescender;
449 }
450
451 float
452 _FontImpl::GetDescenderF(void) const
453 {
454         CRITICAL_SECTION;
455         IF_NOT_CONSTRUCTED(return -1.0f);
456
457         float pcDescender = float(ceil(_pNativeFont->GetDescender().ToDouble()));
458         float vcDescender = _ResUtil::ConvertToVirCoordY(pcDescender);
459
460         if (vcDescender < 0.0f)
461         {
462                 vcDescender *= -1.0f;
463         }
464
465         return vcDescender;
466 }
467
468 result
469 _FontImpl::GetLeftBear(wchar_t character, int& vcLeftBear) const
470 {
471         CRITICAL_SECTION;
472         IF_NOT_CONSTRUCTED(return E_OPERATION_FAILED);
473
474         _Util::FixedPoint22_10 pcLeftBear(0);
475         result r = _pNativeFont->GetLeftBear(character, pcLeftBear);
476
477         // set outparam
478         if (r == E_SUCCESS)
479         {
480                 vcLeftBear = _ResUtil::ConvertToVirCoordX(pcLeftBear.ToInt());
481         }
482
483         return r;
484 }
485
486 result
487 _FontImpl::GetLeftBear(wchar_t character, float& vcLeftBear) const
488 {
489         CRITICAL_SECTION;
490         IF_NOT_CONSTRUCTED(return E_OPERATION_FAILED);
491
492         _Util::FixedPoint22_10 pcLeftBear(0);
493         result r = _pNativeFont->GetLeftBear(character, pcLeftBear);
494
495         if (r == E_SUCCESS)
496         {
497                 vcLeftBear = _ResUtil::ConvertToVirCoordX(pcLeftBear.ToFloat());
498         }
499
500         return r;
501 }
502
503 result
504 _FontImpl::GetRightBear(wchar_t character, int& vcRightBear) const
505 {
506         CRITICAL_SECTION;
507         IF_NOT_CONSTRUCTED(return E_OPERATION_FAILED);
508
509         _Util::FixedPoint22_10 pcRightBear(0);
510         result r = _pNativeFont->GetRightBear(character, pcRightBear);
511
512         // set outparam
513         if (r == E_SUCCESS)
514         {
515                 vcRightBear = _ResUtil::ConvertToVirCoordX(pcRightBear.ToInt());
516         }
517
518         return r;
519 }
520
521 result
522 _FontImpl::GetRightBear(wchar_t character, float& vcRightBear) const
523 {
524         CRITICAL_SECTION;
525         IF_NOT_CONSTRUCTED(return E_OPERATION_FAILED);
526
527         _Util::FixedPoint22_10 pcRightBear(0);
528         result r = _pNativeFont->GetRightBear(character, pcRightBear);
529
530         if (r == E_SUCCESS)
531         {
532                 vcRightBear = _ResUtil::ConvertToVirCoordX(pcRightBear.ToFloat());
533         }
534
535         return r;
536 }
537
538 result
539 _FontImpl::GetTextExtent(const Tizen::Base::String& text, int length, Dimension& vcDim, bool outline) const
540 {
541         CRITICAL_SECTION;
542         IF_NOT_CONSTRUCTED(return E_OPERATION_FAILED);
543
544         int dummyCount = 0 ;
545
546         if (_ResUtil::NeedToConvertCoord())
547         {
548                 Dimension pcDim;
549                 result r = _pNativeFont->GetTextExtent(INT_MAX, _Util::String(text.GetPointer(), text.GetLength(), 0, length), outline, dummyCount, pcDim);
550
551                 if (IsSucceeded(r))
552                 {
553                         vcDim = _ResUtil::ConvertToVirCoord(pcDim);
554                 }
555
556                 return r;
557         }
558         else
559         {
560                 return _pNativeFont->GetTextExtent(INT_MAX, _Util::String(text.GetPointer(), text.GetLength(), 0, length), outline, dummyCount, vcDim);
561         }
562 }
563
564 result
565 _FontImpl::GetTextExtent(const Tizen::Base::String& text, int length, FloatDimension& vcDim, bool outline) const
566 {
567         CRITICAL_SECTION;
568         IF_NOT_CONSTRUCTED(return E_OPERATION_FAILED);
569
570         int dummyCount = 0;
571         Dimension pcDim;
572
573         result r = _pNativeFont->GetTextExtent(INT_MAX, _Util::String(text.GetPointer(), text.GetLength(), 0, length), outline, dummyCount, pcDim);
574
575         if (IsSucceeded(r))
576         {
577                 vcDim.width = _ResUtil::ConvertToVirCoord(static_cast<float>(pcDim.width));
578                 vcDim.height = _ResUtil::ConvertToVirCoord(static_cast<float>(pcDim.height));
579         }
580
581         return r;
582 }
583
584 bool
585 _FontImpl::IsBold(void) const
586 {
587         CRITICAL_SECTION;
588         IF_NOT_CONSTRUCTED(return false);
589
590         return _pNativeFont->IsBold();
591 }
592
593 bool
594 _FontImpl::IsItalic(void) const
595 {
596         CRITICAL_SECTION;
597         IF_NOT_CONSTRUCTED(return false);
598
599         return _pNativeFont->IsItalic();
600 }
601
602 bool
603 _FontImpl::IsPlain(void) const
604 {
605         CRITICAL_SECTION;
606         IF_NOT_CONSTRUCTED(return false);
607
608         return _pNativeFont->IsPlain();
609 }
610
611 bool
612 _FontImpl::IsStrikeOut(void) const
613 {
614         CRITICAL_SECTION;
615         IF_NOT_CONSTRUCTED(return false);
616
617         return _pNativeFont->IsStrikeOut();
618 }
619
620 bool
621 _FontImpl::IsUnderlined(void) const
622 {
623         CRITICAL_SECTION;
624         IF_NOT_CONSTRUCTED(return false);
625
626         return _pNativeFont->IsUnderlined();
627 }
628
629 int
630 _FontImpl::GetSize(void) const
631 {
632         CRITICAL_SECTION;
633         IF_NOT_CONSTRUCTED(return -1);
634
635         return _pCoordHolder->size.required;
636 }
637
638 float
639 _FontImpl::GetSizeF(void) const
640 {
641         CRITICAL_SECTION;
642         IF_NOT_CONSTRUCTED(return -1.0f);
643
644         return _pCoordHolder->sizeF.required;
645 }
646
647 void
648 _FontImpl::SetStrikeOut(bool strikeOut)
649 {
650         CRITICAL_SECTION;
651         IF_NOT_CONSTRUCTED(return);
652
653         _pNativeFont->SetStrikeOut(strikeOut);
654
655         return;
656 }
657
658 void
659 _FontImpl::SetUnderline(bool underline)
660 {
661         CRITICAL_SECTION;
662         IF_NOT_CONSTRUCTED(return);
663
664         _pNativeFont->SetUnderline(underline);
665
666         return;
667 }
668
669 void
670 _FontImpl::SetCharSpace(int vcSpace)
671 {
672         CRITICAL_SECTION;
673         IF_NOT_CONSTRUCTED(return);
674
675         // save it
676         _pCoordHolder->charSpace = vcSpace;
677
678         // convert VC -> PC
679         int pcSpace = _ResUtil::ConvertToPhyCoordWidth(vcSpace);
680
681         _pNativeFont->SetCharSpace(pcSpace);
682
683         return;
684 }
685
686 void
687 _FontImpl::SetCharSpace(float vcSpace)
688 {
689         CRITICAL_SECTION;
690         IF_NOT_CONSTRUCTED(return);
691
692         // save it
693         _pCoordHolder->charSpaceF = vcSpace;
694
695         // convert VC -> PC
696         float pcSpace = _ResUtil::ConvertToPhyCoordWidth(vcSpace);
697
698         _pNativeFont->SetCharSpace(_FloatToIntForPos(pcSpace));
699
700         return;
701 }
702
703 int
704 _FontImpl::GetCharSpace(void) const
705 {
706         CRITICAL_SECTION;
707         IF_NOT_CONSTRUCTED(return 0);
708
709         return _pCoordHolder->charSpace.required;
710 }
711
712 float
713 _FontImpl::GetCharSpaceF(void) const
714 {
715         CRITICAL_SECTION;
716         IF_NOT_CONSTRUCTED(return 0.0f);
717
718         return _pCoordHolder->charSpaceF.required;
719 }
720
721 Tizen::Base::String
722 _FontImpl::GetFaceName(void) const
723 {
724         CRITICAL_SECTION;
725         IF_NOT_CONSTRUCTED(return "");
726
727         return _pNativeFont->GetFaceName();
728 }
729
730 Tizen::Base::Collection::IList*
731 _FontImpl::GetSystemFontListN(void)
732 {
733         CRITICAL_SECTION;
734         return _Font::GetSystemFontListN();
735 }
736
737 Tizen::Base::String
738 _FontImpl::GetFaceName(const Tizen::Base::String& filePath)
739 {
740         CRITICAL_SECTION;
741         return _Font::GetFaceName(filePath);
742 }
743
744 _FontImpl*
745 _FontImpl::CloneN(void)
746 {
747         CRITICAL_SECTION;
748         IF_NOT_CONSTRUCTED(return null);
749
750         std::auto_ptr<_FontImpl> pFontImpl(new (std::nothrow) _FontImpl(*this));
751
752         SysTryReturn(NID_GRP, pFontImpl.get(), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocated memory");
753         SysTryReturn(NID_GRP, pFontImpl->_pNativeFont, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] FontEx::CloneN() has been failed");
754
755         return pFontImpl.release();
756 }
757
758 Font*
759 _FontImpl::CloneN(const Font& font)
760 {
761         CRITICAL_SECTION;
762
763         // check the validation of input param
764         SysTryReturn(NID_GRP, font.__pImpl && font.__pImpl->IsConstructed(), null, E_INVALID_ARG, "[E_INVALID_ARG] Invalid input param given");
765
766         // make sure if the copy construction is well done
767         std::auto_ptr<Font> pFont(new (std::nothrow) Font(font));
768
769         SysTryReturn(NID_GRP, pFont.get() && pFont->__pImpl && pFont->__pImpl->IsConstructed(), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory");
770
771         return pFont.release();
772 }
773
774 result
775 _FontImpl::GetTextExtent(int vcWidth, const Tizen::Base::String& text, int startIndex, int length, bool outline, int& count, Dimension& vcDim) const
776 {
777         CRITICAL_SECTION;
778         IF_NOT_CONSTRUCTED(return E_OPERATION_FAILED);
779
780         SysTryReturnResult(NID_GRP, startIndex >= 0 && length >= 0 && startIndex < text.GetLength(), E_OUT_OF_RANGE,
781                 "The length(%d) & startIndex(%d) of the given text is out of range", length, startIndex);
782
783         if (_ResUtil::NeedToConvertCoord())
784         {
785                 int pcWidth = _ResUtil::ToPhyCoordW(vcWidth);
786                 Dimension pcDim;
787                 result r = _pNativeFont->GetTextExtent(pcWidth, _Util::String(text.GetPointer(), text.GetLength(), startIndex, length), outline, count, pcDim);
788
789                 if (IsSucceeded(r))
790                 {
791                         vcDim = _ResUtil::ConvertToVirCoord(pcDim);
792                 }
793
794                 return r;
795         }
796         else
797         {
798                 return _pNativeFont->GetTextExtent(vcWidth, _Util::String(text.GetPointer(), text.GetLength(), startIndex, length), outline, count, vcDim);
799         }
800 }
801
802 result
803 _FontImpl::GetTextExtent(int vcWidth, const Tizen::Base::String& text, int startIndex, int length, bool outline, const Tizen::Base::String& delimiter, int& count, Dimension& vcDim) const
804 {
805         CRITICAL_SECTION;
806         IF_NOT_CONSTRUCTED(return E_OPERATION_FAILED);
807
808         SysTryReturnResult(NID_GRP, startIndex >= 0 && length >= 0 && startIndex < text.GetLength(), E_OUT_OF_RANGE,
809                 "The length(%d) & startIndex(%d) of the given text is out of range", length, startIndex);
810
811         if (_ResUtil::NeedToConvertCoord())
812         {
813                 int pcWidth = _ResUtil::ToPhyCoordW(vcWidth);
814                 Dimension pcDim;
815                 result r = _pNativeFont->GetTextExtent(pcWidth, _Util::String(text.GetPointer(), text.GetLength(), startIndex, length), outline, delimiter, count, pcDim);
816
817                 if (IsSucceeded(r))
818                 {
819                         vcDim = _ResUtil::ConvertToVirCoord(pcDim);
820                 }
821
822                 return r;
823         }
824         else
825         {
826                 return _pNativeFont->GetTextExtent(vcWidth, _Util::String(text.GetPointer(), text.GetLength(), startIndex, length), outline, delimiter, count, vcDim);
827         }
828 }
829
830 result
831 _FontImpl::GetTextExtent(float vcWidth, const Tizen::Base::String& text, int startIndex, int length, bool outline, int& count, FloatDimension& vcDim) const
832 {
833         CRITICAL_SECTION;
834         IF_NOT_CONSTRUCTED(return E_OPERATION_FAILED);
835
836         SysTryReturnResult(NID_GRP, startIndex >= 0 && length >= 0 && startIndex < text.GetLength(), E_OUT_OF_RANGE,
837                 "The length(%d) & startIndex(%d) of the given text is out of range", length, startIndex);
838
839         int pcWidth = _FloatToIntForPos(_ResUtil::ToPhyCoordW(vcWidth));
840         Dimension pcDim;
841         result r = _pNativeFont->GetTextExtent(pcWidth, _Util::String(text.GetPointer(), text.GetLength(), startIndex, length), outline, count, pcDim);
842
843         if (IsSucceeded(r))
844         {
845                 vcDim.width = _ResUtil::ConvertToVirCoord(static_cast<float>(pcDim.width));
846                 vcDim.height = _ResUtil::ConvertToVirCoord(static_cast<float>(pcDim.height));
847         }
848
849         return r;
850 }
851
852 result
853 _FontImpl::GetTextExtent(float vcWidth, const Tizen::Base::String& text, int startIndex, int length, bool outline, const Tizen::Base::String& delimiter, int& count, FloatDimension& vcDim) const
854 {
855         CRITICAL_SECTION;
856         IF_NOT_CONSTRUCTED(return E_OPERATION_FAILED);
857
858         SysTryReturnResult(NID_GRP, startIndex >= 0 && length >= 0 && startIndex < text.GetLength(), E_OUT_OF_RANGE,
859                 "The length(%d) & startIndex(%d) of the given text is out of range", length, startIndex);
860
861         int pcWidth = _FloatToIntForPos(_ResUtil::ToPhyCoordW(vcWidth));
862         Dimension pcDim;
863         result r = _pNativeFont->GetTextExtent(pcWidth, _Util::String(text.GetPointer(), text.GetLength(), startIndex, length), outline, delimiter, count, pcDim);
864
865         if (IsSucceeded(r))
866         {
867                 vcDim.width = _ResUtil::ConvertToVirCoord(static_cast<float>(pcDim.width));
868                 vcDim.height = _ResUtil::ConvertToVirCoord(static_cast<float>(pcDim.height));
869         }
870
871         return r;
872 }
873
874 result
875 _FontImpl::SetSize(int vcSize)
876 {
877         CRITICAL_SECTION;
878         IF_NOT_CONSTRUCTED(return E_OPERATION_FAILED);
879         SysTryReturnResult(NID_GRP, vcSize > 0, E_INVALID_ARG, "Font size should be greater than 0");
880
881         _pCoordHolder->Reset(vcSize);
882
883         // convert VC -> PC
884         _Util::FixedPoint26_6 pcSize(_ResUtil::ConvertToPhyCoordHeight(vcSize));
885
886         if (vcSize > 0 && pcSize <= 1)
887         {
888                 pcSize = _Util::FixedPoint26_6(1);
889
890                 _pCoordHolder->size.phyCoord = 1;
891                 _pCoordHolder->size.virCoord = vcSize;
892         }
893
894         result r = _pNativeFont->SetSize(pcSize);
895         SysTryReturnResult(NID_GRP, r == E_SUCCESS, E_SYSTEM, "Failed to set the size of _Font");
896
897         return E_SUCCESS;
898 }
899
900 result
901 _FontImpl::SetSize(float vcSize)
902 {
903         CRITICAL_SECTION;
904         IF_NOT_CONSTRUCTED(return E_OPERATION_FAILED);
905         SysTryReturnResult(NID_GRP, vcSize > 0.0f, E_INVALID_ARG, "Font size should be greater than 0");
906
907         _pCoordHolder->Reset(vcSize);
908
909         // convert VC -> PC
910         _Util::FixedPoint26_6 pcSize(_ResUtil::ConvertToPhyCoordHeight(vcSize));
911
912         if (vcSize > 0.0f && pcSize <= 1.0f)
913         {
914                 pcSize = _Util::FixedPoint26_6(1.0f);
915
916                 _pCoordHolder->sizeF.phyCoord = 1.0f;
917                 _pCoordHolder->sizeF.virCoord = vcSize;
918         }
919
920         result r = _pNativeFont->SetSize(pcSize);
921         SysTryReturnResult(NID_GRP, r == E_SUCCESS, E_SYSTEM, "Failed to set the size of _Font");
922
923         return E_SUCCESS;
924 }
925
926 result
927 _FontImpl::SetStyle(int style)
928 {
929         CRITICAL_SECTION;
930         IF_NOT_CONSTRUCTED(return E_OPERATION_FAILED);
931         SysTryReturnResult(NID_GRP, style > FONT_STYLE_MIN && style <= (FONT_STYLE_PLAIN | FONT_STYLE_BOLD | FONT_STYLE_ITALIC), E_INVALID_ARG,
932                 "Style(%d) is invalid", style);
933
934         result r = _pNativeFont->SetStyle(style);
935         SysTryReturnResult(NID_GRP, r == E_SUCCESS, E_SYSTEM, "Failed to set the style of _Font");
936
937         return E_SUCCESS;
938 }
939
940 int
941 _FontImpl::GetStyle(void) const
942 {
943         CRITICAL_SECTION;
944         IF_NOT_CONSTRUCTED(return FONT_STYLE_PLAIN);
945
946         return _pNativeFont->GetStyle();
947 }
948
949 int
950 _FontImpl::GetLeading(void) const
951 {
952         CRITICAL_SECTION;
953         IF_NOT_CONSTRUCTED(return -1);
954
955         int pcLeading = _DoubleToIntForPos(ceil(_pNativeFont->GetLeading().ToDouble()));
956
957         for (int i = pcLeading; i < INT_MAX; i++)
958         {
959                 if (_ResUtil::ConvertToPhyCoord(_ResUtil::ConvertToVirCoordY(i)) >= pcLeading)
960                 {
961                         pcLeading = i;
962                         break;
963                 }
964         }
965
966         int vcLeading = _ResUtil::ConvertToVirCoordY(pcLeading);
967
968         return vcLeading;
969 }
970
971 float
972 _FontImpl::GetLeadingF(void) const
973 {
974         CRITICAL_SECTION;
975         IF_NOT_CONSTRUCTED(return -1.0f);
976
977         float pcLeading = float(ceil(_pNativeFont->GetLeading().ToDouble()));
978         float vcLeading = _ResUtil::ConvertToVirCoordY(pcLeading);
979
980         return vcLeading;
981 }
982
983 _FontImpl*
984 _FontImpl::GetInstance(Font& font)
985 {
986         CRITICAL_SECTION;
987         return (&font != null) ? font.__pImpl : null;
988 }
989
990 const _FontImpl*
991 _FontImpl::GetInstance(const Font& font)
992 {
993         CRITICAL_SECTION;
994         return (&font != null) ? font.__pImpl : null;
995 }
996
997 bool
998 _FontImpl::UpdateDefaultFont(const Tizen::Base::String& key)
999 {
1000         CRITICAL_SECTION;
1001         return _Font::UpdateDefaultFont(key);
1002 }
1003
1004 result
1005 _FontImpl::GetTextExtentList(const Tizen::Base::String& string, int startIndex, int length, Tizen::Base::Collection::ArrayListT<_FloatPair>& outList) const
1006 {
1007         CRITICAL_SECTION;
1008         IF_NOT_CONSTRUCTED(return E_OPERATION_FAILED);
1009
1010         SysTryReturnResult(NID_GRP, startIndex >= 0 && length >= 0 && startIndex < string.GetLength(), E_OUT_OF_RANGE,
1011                 "The length(%d) & startIndex(%d) of the given text is out of range", length, startIndex);
1012
1013         _Util::String text(string.GetPointer(), string.GetLength(), startIndex, length);
1014         _Util::AccumList<_Util::Pair<int, int> > outAccumList;
1015
1016         result r = _pNativeFont->GetTextExtentList(text, outAccumList);
1017
1018         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Failed to get the internal text extent information", GetErrorMessage(r));
1019
1020         outList.RemoveAll();
1021
1022         for (_Util::AccumList<_Util::Pair<int, int> >::Iterator iter = outAccumList.Begin(); iter != outAccumList.End(); ++iter)
1023         {
1024                 _FloatPair pairF =
1025                 {
1026                         _ResUtil::ConvertToVirCoord(static_cast<float>(iter->first)),
1027                         _ResUtil::ConvertToVirCoord(static_cast<float>(iter->second))
1028                 };
1029
1030                 outList.Add(pairF);
1031         }
1032
1033         return E_SUCCESS;
1034 }
1035
1036 result
1037 _FontImpl::__GetTextExtent(const wchar_t* text, int textLength, int length, FloatDimension& vcDim, bool outline) const
1038 {
1039         // This method must synchronize with _FontImpl::GetTextExtent(const Tizen::Base::String& text, int length, FloatDimension& vcDim, bool outline)
1040
1041         CRITICAL_SECTION;
1042         IF_NOT_CONSTRUCTED(return E_OPERATION_FAILED);
1043
1044         int dummyCount = 0;
1045         Dimension pcDim;
1046
1047         result r = _pNativeFont->GetTextExtent(INT_MAX, _Util::String(text, textLength, 0, length), outline, dummyCount, pcDim);
1048
1049         if (IsSucceeded(r))
1050         {
1051                 vcDim.width = _ResUtil::ConvertToVirCoord(static_cast<float>(pcDim.width));
1052                 vcDim.height = _ResUtil::ConvertToVirCoord(static_cast<float>(pcDim.height));
1053         }
1054
1055         return r;
1056 }
1057
1058 result
1059 _FontImpl::__GetTextExtent(float vcWidth, const wchar_t* text, int textLength, int startIndex, int length, bool outline, int& count, FloatDimension& vcDim) const
1060 {
1061         // This method must synchronize with _FontImpl::GetTextExtent(float vcWidth, const Tizen::Base::String& text, int startIndex, int length, bool outline, int& count, FloatDimension& vcDim)
1062
1063         CRITICAL_SECTION;
1064         IF_NOT_CONSTRUCTED(return E_OPERATION_FAILED);
1065
1066         SysTryReturnResult(NID_GRP, startIndex >= 0 && length >= 0 && startIndex < textLength, E_OUT_OF_RANGE,
1067                 "The length(%d) & startIndex(%d) of the given text is out of range", length, startIndex);
1068
1069         int pcWidth = _FloatToIntForPos(_ResUtil::ToPhyCoordW(vcWidth));
1070         Dimension pcDim;
1071         result r = _pNativeFont->GetTextExtent(pcWidth, _Util::String(text, textLength, startIndex, length), outline, count, pcDim);
1072
1073         if (IsSucceeded(r))
1074         {
1075                 vcDim.width = _ResUtil::ConvertToVirCoord(static_cast<float>(pcDim.width));
1076                 vcDim.height = _ResUtil::ConvertToVirCoord(static_cast<float>(pcDim.height));
1077         }
1078
1079         return r;
1080 }
1081
1082 }} // Tizen::Graphics
1083
1084
1085 namespace Tizen { namespace Graphics
1086 {
1087
1088 TextBidiHint _bidiHint = TEXT_BIDI_HINT_NONE;
1089
1090 void
1091 _SetTextBidiHint(TextBidiHint bidiHint)
1092 {
1093         switch (bidiHint)
1094         {
1095         case TEXT_BIDI_HINT_NONE:
1096         case TEXT_BIDI_HINT_LTR:
1097         case TEXT_BIDI_HINT_RTL:
1098                 _bidiHint = bidiHint;
1099                 break;
1100         }
1101 }
1102
1103 TextBidiHint
1104 _GetTextBidiHint(void)
1105 {
1106         return _bidiHint;
1107 }
1108
1109 }} // Tizen::Graphics
1110
1111
1112 namespace Tizen { namespace Graphics
1113 {
1114
1115 void
1116 _SetTextBidiBase(TextBidiBase bidiBase)
1117 {
1118         switch (bidiBase)
1119         {
1120         case TEXT_BIDI_BASE_LTR:
1121                 _TextBidiUtil::SetTextBidiBase(true);
1122                 break;
1123         case TEXT_BIDI_BASE_RTL:
1124                 _TextBidiUtil::SetTextBidiBase(false);
1125                 break;
1126         }
1127 }
1128
1129 TextBidiBase
1130 _GetTextBidiBase(void)
1131 {
1132         return (_TextBidiUtil::IsTextBidiBaseLtr()) ? TEXT_BIDI_BASE_LTR : TEXT_BIDI_BASE_RTL;
1133 }
1134
1135 }} // Tizen::Graphics
1136
1137 ////////////////////////////////////////////////////////////////////////////////
1138 //
1139 // Temporary code for test case
1140 //
1141 ////////////////////////////////////////////////////////////////////////////////
1142
1143 #include <vector>
1144 #include <utility>
1145 #include "FGrp_FontUtil.h"
1146
1147 namespace Tizen { namespace Graphics
1148 {
1149         _OSP_EXPORT_ bool _TestGetTextExtentList(Tizen::Graphics::Font& font, const Tizen::Base::String& string, std::vector<std::pair<int, int> >& outList)
1150         {
1151                 _Font* pInternalFont = _GetFontEx(font);
1152                 _Util::String text(string.GetPointer(), string.GetLength());
1153                 _Util::AccumList<_Util::Pair<int, int> > outAccumList;
1154
1155                 if (pInternalFont->GetTextExtentList(text, outAccumList) != E_SUCCESS)
1156                 {
1157                         return false;
1158                 }
1159
1160                 outList.clear();
1161
1162                 for (_Util::AccumList<_Util::Pair<int, int> >::Iterator iter = outAccumList.Begin(); iter != outAccumList.End(); ++iter)
1163                 {
1164                         outList.push_back(std::make_pair(iter->first, iter->second));
1165                 }
1166
1167                 return true;
1168         }
1169
1170 }} // Tizen::Graphics