Tizen 2.1 base
[framework/osp/uifw.git] / src / graphics / text / FGrp_TextTextSimple.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
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
8 //
9 //     http://floralicense.org/license/
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_TextTextSimple.cpp
20  * @brief       This is the implementation file for TextSimple class.
21  */
22
23 #include <new>
24 #include <FBaseString.h>
25 #include <FBaseSysLog.h>
26 #include "FGrp_CanvasImpl.h"
27 #include "FGrp_BitmapImpl.h"
28 #include "FGrp_TextTextSimple.h"
29 #include "FGrp_TextTextUtility.h"
30 #include "FGrp_FontImpl.h"
31 #include "../FGrp_BitmapUtil.h"
32 #include "../FGrp_Font.h"
33 #include "../FGrp_Canvas.h"
34
35 namespace // unnamed
36 {
37         const int DEFAULT_FONT_SIZE = 42;
38         const int LINE_FEED_WIDTH = 8;
39 }
40
41 namespace Tizen { namespace Graphics
42 {
43
44 namespace _Text
45 {
46
47 TextSimple::TextSimple(const wchar_t* pText, int length, TextElementSourceType sourceType, Font* pFont,
48                 const Color& foregroundColor, const Color& backgroundColor, const Color& outlineColor)
49         : TextElement()
50 {
51         _type = TEXT_ELEMENT_TYPE_TEXT;
52         _sourceType = sourceType;
53         _hasFocus = false;
54         _isAlternateLookEnabled = false;
55
56         if (pFont != null)
57         {
58                 _pFont = _FontImpl::CloneN(const_cast <Font&>(*pFont));
59         }
60         else
61         {
62                 _pFont = new (std::nothrow) Font();
63                 _pFont->Construct(FONT_STYLE_PLAIN, DEFAULT_FONT_SIZE);
64         }
65
66         _foregroundColor = foregroundColor;
67         _backgroundColor = backgroundColor;
68         _outlineColor = outlineColor;
69         _outline = false;
70
71         if (sourceType == TEXT_ELEMENT_SOURCE_TYPE_INTERNAL)
72         {
73                 wchar_t* pTempText = new (std::nothrow) wchar_t[length + 1];
74                 if (pTempText)
75                 {
76                         int test = (int) _pText;
77                         test = test & 0x03;
78
79                         TextUtility::CopyText(pTempText, pText, length);
80                         pTempText[length] = 0;
81
82                         _pText = pTempText;
83                 }
84         }
85         else
86         {
87                 _pText = pText;
88         }
89
90         _offset = 0;
91         _length = length;
92         _isBackgroundDrawingModeEnabled = false;
93         _userWrap = TEXT_OBJECT_WRAP_TYPE_WORD;
94         __pBitmap = null;
95 }
96
97 TextSimple::~TextSimple(void)
98 {
99         if (_sourceType == TEXT_ELEMENT_SOURCE_TYPE_INTERNAL)
100         {
101                 if (_pText)
102                 {
103                         delete[] _pText;
104                         _pText = null;
105                 }
106         }
107
108         if (__pBitmap)
109         {
110                 delete __pBitmap;
111                 __pBitmap = null;
112         }
113
114         if (_pFont)
115         {
116                 delete _pFont;
117                 _pFont = null;
118         }
119 }
120
121 int
122 TextSimple::ForwardAnalyze(int startTextIndex, int textLength, int maxWidth, TextObjectWrapType wrap, int& actualLength,
123                                                         int& width, int& height)
124 {
125         int charCount = 0;
126         int r = TEXT_RETBY_NORMAL;
127
128         if (textLength > _length)
129         {
130                 textLength = _length;
131         }
132
133         if (textLength == 0)
134         {
135                 actualLength = textLength;
136                 width = 0;
137                 height = 0;
138
139                 return TEXT_RETBY_NORMAL;
140         }
141
142         if (__pBitmap)
143         {
144                 int bitmapWidth = __pBitmap->GetWidth();
145                 int bitmapHeight = __pBitmap->GetHeight();
146
147                 if (maxWidth < bitmapWidth)
148                 {
149                         actualLength = 0;
150                         width = 0;
151                         height = 0;
152
153                         return TEXT_RETBY_OVERWIDTH;
154                 }
155                 else
156                 {
157                         actualLength = _length;
158                         width = bitmapWidth;
159                         height = bitmapHeight;
160
161                         return TEXT_RETBY_NORMAL;
162                 }
163         }
164
165         Font* pCurrentFont = GetCurrentFont();
166         _Font* pFont = _Font::GetInstance(*_FontImpl::GetInstance(*pCurrentFont));
167         SysTryReturn(NID_GRP
168                         , pFont
169                         , -1, E_SYSTEM, "[E_SYSTEM] Fail to get native font instance.");
170
171         const wchar_t* pText = &_pText[startTextIndex];
172
173         switch (wrap)
174         {
175         case TEXT_OBJECT_WRAP_TYPE_NONE:
176         {
177                 if (_userWrap == TEXT_OBJECT_WRAP_TYPE_NONE)
178                 {
179                         wchar_t* pModifiedText = new (std::nothrow) wchar_t[textLength + 1];
180                         SysTryReturn(NID_GRP
181                                 , pModifiedText
182                                 , -1, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
183
184                         int length = ConvertEnterToSpace(pModifiedText, pText, textLength);
185                         pModifiedText[length] = 0;
186
187                         actualLength = TextUtility::GetCharCountInWidth(pFont, pModifiedText, length, maxWidth, _outline, width, height);
188
189                         charCount = textLength;
190                         r = TEXT_RETBY_NORMAL;
191
192                         delete[] pModifiedText;
193                         pModifiedText = null;
194                 }
195                 else
196                 {
197                         actualLength = TextUtility::GetCharCountInWidth(pFont, pText, textLength, maxWidth, _outline, width, height);
198                         charCount = textLength;
199                         r = TEXT_RETBY_NORMAL;
200                 }
201         }
202         break;
203
204         case TEXT_OBJECT_WRAP_TYPE_CHARACTER:
205                 r = GetSentenceLength(pText, textLength, charCount);
206                 actualLength = TextUtility::GetCharCountInWidth(pFont, pText, charCount, maxWidth, _outline, width, height);
207                 if (_pText[startTextIndex + actualLength] == TEXT_LINE_FEED ||
208                                 _pText[startTextIndex + actualLength] == TEXT_CARRIAGE_RETURN)
209                 {
210                         (actualLength)++;
211                         r = TEXT_RETBY_LINEFEED;
212                 }
213                 break;
214
215         case TEXT_OBJECT_WRAP_TYPE_WORD:
216                 actualLength = TextUtility::GetCharCountInWidth(pFont, pText, textLength, maxWidth, _outline, width, height);
217                 int widthcheck = width;
218
219                 if (_pText[startTextIndex + actualLength] == TEXT_LINE_FEED || _pText[startTextIndex + actualLength] == TEXT_CARRIAGE_RETURN)
220                 {
221                         actualLength++;
222                         r = TEXT_RETBY_LINEFEED;
223                 }
224                 else if (textLength == actualLength)
225                 {
226                         r = TEXT_RETBY_LIMITLENGTH;
227                 }
228                 else if (actualLength == 0)
229                 {
230                         charCount = 0;
231                         r = TEXT_RETBY_LIMITWIDTH;
232                 }
233                 else
234                 {
235                         r = GetWordWrapLengthEx(pText, actualLength, charCount);
236
237                         if (charCount < actualLength)
238                         {
239                                 if (charCount == 0)
240                                 {
241                                         r = TEXT_RETBY_LIMITWIDTH;
242                                 }
243                                 else
244                                 {
245                                         r = TEXT_RETBY_NORMAL;
246                                 }
247                         }
248
249                         if (charCount != 0)
250                         {
251                                 if (charCount > (actualLength / 2))
252                                 {
253                                         const wchar_t* pExtraText = &_pText[startTextIndex + charCount];
254                                         int overCharCount = TextUtility::GetCharCountInWidth(pFont, pExtraText, actualLength - charCount, maxWidth, _outline, width, height);
255                                         actualLength = actualLength - overCharCount;
256                                         width = widthcheck - width;
257                                 }
258                                 else
259                                 {
260                                         actualLength = TextUtility::GetCharCountInWidth(pFont, pText, charCount, maxWidth, _outline, width, height);
261                                 }
262
263                                 actualLength = charCount;
264                         }
265                 }
266
267                 break;
268         }
269
270         if (height == 0 && (textLength > 0))
271         {
272                 height = pFont->GetLeading();
273         }
274
275         if (actualLength < charCount)
276         {
277                 r = TEXT_RETBY_LIMITWIDTH;
278         }
279
280         return r;
281 }
282
283 bool
284 TextSimple::IsKorean(const wchar_t* ch) const
285 {
286         if (0xAC00 <= *ch && *ch <= 0xD7A3)
287         {
288                 return true;
289         }
290
291         if (0x3130 <= *ch && *ch <= 0x318F)
292         {
293                 return true;
294         }
295
296         if (0x1100 <= *ch && *ch <= 0x11FF)
297         {
298                 return true;
299         }
300
301         return false;
302 }
303
304 bool
305 TextSimple::IsChinese(const wchar_t* ch) const
306 {
307         if (0X2E80 <= *ch && *ch <= 0x2FFF)
308         {
309                 return true;
310         }
311
312         else if (0x3220 <= *ch && *ch <= 0x3243)
313         {
314                 return true;
315         }
316
317         else if (0x3280 <= *ch && *ch <= 0x32CB)
318         {
319                 return true;
320         }
321
322         else if (0x3400 <= *ch && *ch <= 0x4DBF)
323         {
324                 return true;
325         }
326
327         else if (0x4E00 <= *ch && *ch <= 0x9FFF)
328         {
329                 return true;
330         }
331
332         else if (0xF900 <= *ch && *ch <= 0xFAFF)
333         {
334                 return true;
335         }
336
337         return false;
338 }
339
340 result
341 TextSimple::GetRegion(int textIndex, int textLength, int& width, int& height) const
342 {
343         const wchar_t* pText = null;
344         Font* pCurrentFont = GetCurrentFont();
345         SysTryReturn(NID_GRP
346                 , pCurrentFont
347                 , E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] This instance is not line wrapped yet.");
348
349         _Font* pFont = _Font::GetInstance(*_FontImpl::GetInstance(*pCurrentFont));
350         SysTryReturn(NID_GRP
351                         , pFont
352                         , E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get native font instance.");
353
354         if (textLength > _length)
355         {
356                 textLength = _length;
357         }
358
359         if (textLength == 0)
360         {
361                 width = 0;
362                 height = 0;
363
364                 return E_SUCCESS;
365         }
366
367         if (__pBitmap)
368         {
369                 width = __pBitmap->GetWidth();
370                 height = __pBitmap->GetHeight();
371
372                 return E_SUCCESS;
373         }
374
375         pText = &_pText[textIndex];
376
377         switch (_userWrap)
378         {
379         case TEXT_OBJECT_WRAP_TYPE_NONE:
380         {
381                 wchar_t* pModifiedText = new (std::nothrow) wchar_t[textLength + 1];
382                 SysTryReturn(NID_GRP
383                         , pModifiedText
384                         , E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
385
386                 int length = ConvertEnterToSpace(pModifiedText, pText, textLength);
387                 pModifiedText[textLength] = 0;
388
389                 TextUtility::GetTextExtent(pFont, pModifiedText, length, _outline, width, height);
390
391                 delete[] pModifiedText;
392                 pModifiedText = null;
393         }
394         break;
395
396         case TEXT_OBJECT_WRAP_TYPE_CHARACTER:
397                 // fall through
398         case TEXT_OBJECT_WRAP_TYPE_WORD:
399                 TextUtility::GetTextExtent(pFont, pText, textLength, _outline, width, height);
400                 break;
401         }
402
403         if (height == 0 && (textLength > 0))
404         {
405                 height = pFont->GetLeading();
406         }
407
408         return E_SUCCESS;
409 }
410
411 result
412 TextSimple::GetBlockRegion(int textIndex, int textLength, int& width, int& height) const
413 {
414         const wchar_t* pText = null;
415         Font* pCurrentFont = GetCurrentFont();
416         SysTryReturn(NID_GRP
417                 , pCurrentFont
418                 , E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] This instance is not line wrapped yet.");
419
420         _Font* pFont = _Font::GetInstance(*_FontImpl::GetInstance(*pCurrentFont));
421         SysTryReturn(NID_GRP
422                         , pFont
423                         , E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get native font instance.");
424
425         if (textLength > _length)
426         {
427                 textLength = _length;
428         }
429
430         if (textLength == 0)
431         {
432                 width = 0;
433                 height = 0;
434
435                 return E_SUCCESS;
436         }
437
438         if (__pBitmap)
439         {
440                 width = __pBitmap->GetWidth();
441                 height = __pBitmap->GetHeight();
442
443                 return E_SUCCESS;
444         }
445
446         pText = &_pText[textIndex];
447
448         switch (_userWrap)
449         {
450         case TEXT_OBJECT_WRAP_TYPE_NONE:
451         {
452                 wchar_t* pModifiedText = new (std::nothrow) wchar_t[textLength + 1];
453                 SysTryReturn(NID_GRP
454                         , pModifiedText
455                         , E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
456
457                 int length = ConvertEnterToSpace(pModifiedText, pText, textLength);
458                 pModifiedText[textLength] = 0;
459
460                 TextUtility::GetTextExtent(pFont, pModifiedText, length, _outline, width, height);
461
462                 delete[] pModifiedText;
463                 pModifiedText = null;
464         }
465         break;
466
467         case TEXT_OBJECT_WRAP_TYPE_CHARACTER:
468                 // fall through
469         case TEXT_OBJECT_WRAP_TYPE_WORD:
470                 TextUtility::GetTextExtent(pFont, pText, textLength, _outline, width, height);
471
472                 if (pText[textLength-1] == TEXT_LINE_FEED || pText[textLength-1] == TEXT_CARRIAGE_RETURN)
473                 {
474                         width += LINE_FEED_WIDTH;
475                 }
476                 break;
477         }
478
479         if (height == 0 && (textLength > 0))
480         {
481                 height = pFont->GetLeading();
482         }
483
484         return E_SUCCESS;
485 }
486
487 int
488 TextSimple::GetHeight(void) const
489 {
490         Font* pFont = GetCurrentFont();
491         SysTryReturn(NID_GRP
492                 , pFont
493                 , E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] This instance is not line wrapped yet.");
494
495         int maxHeight = 0;
496
497         if (__pBitmap)
498         {
499                 maxHeight = __pBitmap->GetHeight();
500         }
501         else
502         {
503                 maxHeight = TextUtility::GetFontMaxHeight(pFont);
504         }
505
506         return maxHeight;
507 }
508
509 result
510 TextSimple::Draw(_CanvasImpl& canvasImpl, Rectangle& displayRect, int startTextIndex, int textLength,
511                 const TextObjectAlignment align, const TextObjectActionType action)
512 {
513         SysTryReturn(NID_GRP
514                         , textLength <= _length
515                         , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
516
517         if (textLength == 0)
518         {
519                 return E_SUCCESS;
520         }
521
522         result r = E_SUCCESS;
523         _Canvas* pCanvas = _Canvas::GetInstance(canvasImpl);
524         SysTryReturn(NID_GRP
525                         , pCanvas
526                         , E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get native canvas instance.");
527
528         if (__pBitmap)
529         {
530                 r = pCanvas->DrawBitmap(Point(displayRect.x, displayRect.y), *GetBitmapEx(*_BitmapImpl::GetInstance(*__pBitmap)));
531                 SysTryReturn(NID_GRP
532                         , r == E_SUCCESS
533                         , r, r, "[%s] Propagating.", GetErrorMessage(r));
534
535                 return E_SUCCESS;
536         }
537
538         Color foregroundColor = GetCurrentForegroundColor();
539         pCanvas->SetForegroundColor(foregroundColor);
540
541         Color backgroundColor = GetCurrentBackgroundColor();
542         pCanvas->SetBackgroundColor(backgroundColor);
543
544         Color outlineColor = GetCurrentOutlineColor();
545
546         Font* pCurrentFont = GetCurrentFont();
547         SysTryReturn(NID_GRP
548                 , pCurrentFont
549                 , E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] This instance is not line wrapped yet.");
550
551         _Font* pFont = _Font::GetInstance(*_FontImpl::GetInstance(*pCurrentFont));
552         SysTryReturn(NID_GRP
553                         , pFont
554                         , E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get native font instance.");
555
556         r = pCanvas->SetPriorityFont(*pFont);
557         SysTryReturn(NID_GRP
558                         , r == E_SUCCESS
559                         , r, r, "[%s] Propagating.", GetErrorMessage(r));
560
561         if (_userWrap != TEXT_OBJECT_WRAP_TYPE_NONE)
562         {
563                 if (_outline)
564                 {
565                         return TextUtility::DrawOutlineText(*pCanvas, displayRect.x, displayRect.y, &_pText[startTextIndex], textLength, outlineColor);
566                 }
567                 else
568                 {
569                         return TextUtility::DrawText(*pCanvas, displayRect.x, displayRect.y, &_pText[startTextIndex], textLength);
570                 }
571         }
572         else
573         {
574                 wchar_t* pModifiedText = new (std::nothrow) wchar_t[textLength + 1];
575                 SysTryReturn(NID_GRP
576                         , pModifiedText
577                         , E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
578
579                 int length = ConvertEnterToSpace(pModifiedText, &_pText[startTextIndex], textLength);
580                 pModifiedText[length] = 0;
581
582                 if (_outline)
583                 {
584                         TextUtility::DrawOutlineText(*pCanvas, displayRect.x, displayRect.y, pModifiedText, length, outlineColor);
585                 }
586                 else
587                 {
588                         TextUtility::DrawText(*pCanvas, displayRect.x, displayRect.y, pModifiedText, length);
589                 }
590
591                 delete[] pModifiedText;
592                 pModifiedText = null;
593
594                 return E_SUCCESS;
595         }
596
597         return E_SUCCESS;
598 }
599
600 TextElement*
601 TextSimple::CloneN(TextComponentInfoValueType type, unsigned int value)
602 {
603         TextSimple* pSimpleTextElement = null;
604
605         pSimpleTextElement = new (std::nothrow) TextSimple(_pText, _length, TEXT_ELEMENT_SOURCE_TYPE_EXTERNAL, _pFont,
606                                                                                                                    _foregroundColor, _backgroundColor, _outlineColor);
607
608         SysTryReturn(NID_GRP
609                 , pSimpleTextElement
610                 , null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
611
612         TextElement::CopyMembers(pSimpleTextElement);
613
614         pSimpleTextElement->SetValue(SET_TEXT_OFFSET, _offset);
615         pSimpleTextElement->SetValue(SET_ALTERNATE_LOOK, _isAlternateLookEnabled);
616         pSimpleTextElement->SetValue(type, value);
617         pSimpleTextElement->SetUserWrap(_userWrap);
618
619         return pSimpleTextElement;
620 }
621
622 TextElement*
623 TextSimple::CopyN(int startTextIndex, int textLength)
624 {
625         const wchar_t* pText = null;
626
627         TextSimple* pSimpleTextElement = null;
628
629         if (startTextIndex >= _length)
630         {
631                 return null;
632         }
633
634         if (startTextIndex + textLength > _length)
635         {
636                 textLength = _length - startTextIndex;
637         }
638
639         if (textLength <= 0)
640         {
641                 return null;
642         }
643
644         pText = &_pText[_offset + startTextIndex];
645
646         pSimpleTextElement = new (std::nothrow) TextSimple(pText, textLength, _sourceType, _pFont,
647                                                                                                                    _foregroundColor, _backgroundColor, _outlineColor);
648
649         SysTryReturn(NID_GRP
650                         , pSimpleTextElement
651                         , false, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Insufficient memory.");
652
653         pSimpleTextElement->_isBackgroundDrawingModeEnabled = _isBackgroundDrawingModeEnabled;
654
655         return pSimpleTextElement;
656 }
657
658 unsigned int
659 TextSimple::GetValue(TextComponentInfoValueType type) const
660 {
661         switch (type)
662         {
663         case SET_FONT:
664                 // fall through
665                 return (unsigned int) _pFont;
666
667         case SET_FONT_FGCOLOR:
668                 // fall through
669                 return (unsigned int) _foregroundColor.GetRGB32();
670
671         case SET_FONT_BGCOLOR:
672                 // fall through
673                 return (unsigned int) _backgroundColor.GetRGB32();
674
675         case SET_FONT_OUTLINECOLOR:
676                 // fall through
677                 return (unsigned int) _outlineColor.GetRGB32();
678
679         case SET_TEXT_OFFSET:
680                 // fall through
681                 return (unsigned int) _offset;
682
683         case SET_ALTERNATE_LOOK:
684                 // fall through
685                 return (unsigned int) _isAlternateLookEnabled;
686
687         case SET_ALTERNATIVE_FGCOLOR:
688                 // fall through
689                 return (unsigned int) GetAlternativeForegroundColor().GetRGB32();
690
691         default:
692                 // fall through
693                 return -1;
694         }
695
696         return 0;
697 }
698
699 result
700 TextSimple::SetValue(TextComponentInfoValueType type, unsigned int value)
701 {
702         result r = E_SUCCESS;
703         Font* pFont = null;
704
705         switch (type)
706         {
707         case SET_FONT:
708         {
709                 if (!(Font*) value)
710                 {
711                         return E_INVALID_ARG;
712                 }
713
714                 pFont = _FontImpl::CloneN(const_cast <Font&>(*(Font*) value));
715                 r = GetLastResult();
716                 SysTryReturn(NID_GRP
717                         , pFont
718                         , r, r, "[%s] Propagating.", GetErrorMessage(r));
719
720                 if (_pFont)
721                 {
722                         delete _pFont;
723                         _pFont = null;
724                 }
725                 _pFont = pFont;
726         }
727         break;
728
729         case SET_FONT_FGCOLOR:
730                 _foregroundColor = Color(value);
731                 break;
732
733         case SET_FONT_BGCOLOR:
734                 _backgroundColor = Color(value);
735                 break;
736
737         case SET_FONT_OUTLINECOLOR:
738                 _outlineColor = Color(value);
739                 break;
740
741         case SET_TEXT_OFFSET:
742                 _offset = (int) value;
743                 break;
744
745         case SET_ALLVALUE_CLONE:
746                 break;
747
748         case SET_ALTERNATE_LOOK:
749                 _isAlternateLookEnabled = (bool) value;
750                 break;
751
752         case SET_ALTERNATIVE_FGCOLOR:
753                 SetAlternativeForegroundColor(Color(value));
754                 break;
755
756         default:
757                 break;
758         }
759
760         return E_SUCCESS;
761 }
762
763 result
764 TextSimple::SetFont(const Font* pFont)
765 {
766         SysTryReturn(NID_GRP
767                 , pFont
768                 , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
769
770         result r = E_SUCCESS;
771         Font* pTmpFont = null;
772
773         pTmpFont = _FontImpl::CloneN(const_cast <Font&>(*pFont));
774         r = GetLastResult();
775         SysTryReturn(NID_GRP
776                 , pTmpFont
777                 , r, r, "[%s] Propagating.", GetErrorMessage(r));
778
779         if (_pFont)
780         {
781                 delete _pFont;
782                 _pFont = null;
783         }
784         _pFont = pTmpFont;
785
786         return E_SUCCESS;
787 }
788
789 void
790 TextSimple::SetForegroundColor(const Color& color)
791 {
792         _foregroundColor = color;
793 }
794
795 void
796 TextSimple::SetBackgroundColor(const Color& color)
797 {
798         _backgroundColor = color;
799 }
800
801 void
802 TextSimple::SetOutlineColor(const Color& color)
803 {
804         _outlineColor = color;
805         _outline = true;
806 }
807
808 const Font*
809 TextSimple::GetFont(void) const
810 {
811         return _pFont;
812 }
813
814 Color
815 TextSimple::GetForegroundColor(void) const
816 {
817         return _foregroundColor;
818 }
819
820 Color
821 TextSimple::GetBackgroundColor(void) const
822 {
823         return _backgroundColor;
824 }
825
826 Color
827 TextSimple::GetOutlineColor(void) const
828 {
829         return _outlineColor;
830 }
831
832 result
833 TextSimple::SetTextOffset(int offset)
834 {
835         SysTryReturn(NID_GRP
836                 , offset >= 0
837                 , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
838
839         _offset = offset;
840
841         return E_SUCCESS;
842 }
843
844 int
845 TextSimple::GetTextOffset(void) const
846 {
847         return _offset;
848 }
849
850 const wchar_t*
851 TextSimple::GetTextSource(void) const
852 {
853         return _pText;
854 }
855
856 const wchar_t*
857 TextSimple::GetText(void) const
858 {
859         return &_pText[_offset];
860 }
861
862 bool
863 TextSimple::IsSame(wchar_t* pText, Font* pFont, const Color& fgColor,
864                                    const Color& bgColor, const Color& outlineColor)
865 {
866         if (_pText != pText)
867         {
868                 return false;
869         }
870
871         if (!TextUtility::IsSameFontAttribute(_pFont, pFont))
872         {
873                 return false;
874         }
875
876         if (_foregroundColor != fgColor)
877         {
878                 return false;
879         }
880
881         if (_backgroundColor != bgColor)
882         {
883                 return false;
884         }
885
886         if (_outlineColor != outlineColor)
887         {
888                 return false;
889         }
890
891         return true;
892 }
893
894 result
895 TextSimple::ChangeTextOffset(wchar_t* pText, int gap)
896 {
897         SysTryReturn(NID_GRP
898                 , _pText == pText
899                 , E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is invalid.");
900
901         _offset += gap;
902
903         return E_SUCCESS;
904 }
905
906 int
907 TextSimple::GetSentenceLength(const wchar_t* pText, int textLength, int& actualLength) const
908 {
909         int length = 0;
910
911         actualLength = 0;
912         length = textLength;
913
914         if (*pText == TEXT_LINE_FEED || *pText == TEXT_CARRIAGE_RETURN)
915         {
916                 wchar_t mch = *pText;
917                 pText--;
918
919                 if (mch != *pText && (*pText == TEXT_LINE_FEED || *pText == TEXT_CARRIAGE_RETURN))
920                 {
921                         actualLength++;
922                         length++;
923                         pText++;
924                 }
925
926                 return TEXT_RETBY_LINEFEED;
927         }
928         else
929         {
930                 while (length && (*pText != 0))
931                 {
932                         actualLength++;
933                         pText++;
934                         length--;
935
936                         if (*pText == TEXT_LINE_FEED || *pText == TEXT_PARAGRAPH_SEPARATOR)
937                         {
938                                 actualLength++;
939                                 pText++;
940                                 length--;
941
942                                 if (*pText == TEXT_CARRIAGE_RETURN)
943                                 {
944                                         actualLength++;
945                                         pText++;
946                                         length--;
947                                 }
948
949                                 return TEXT_RETBY_LINEFEED;
950                         }
951                 }
952         }
953
954         if (length == 0)
955         {
956                 return TEXT_RETBY_LIMITLENGTH;
957         }
958
959         return TEXT_RETBY_NORMAL;
960 }
961
962 int
963 TextSimple::GetWordWrapLength(const wchar_t* pText, int textLength, int& actualLength) const
964 {
965         int length = textLength;
966         actualLength = 0;
967
968         if (*pText == (wchar_t)L' ' || *pText == TEXT_OBJ_CHARACTER)
969         {
970                 actualLength++;
971                 return TEXT_RETBY_NORMAL;
972         }
973         else if (*pText == TEXT_LINE_FEED || *pText == TEXT_CARRIAGE_RETURN
974                          || *pText == TEXT_PARAGRAPH_SEPARATOR)
975         {
976                 wchar_t mch = *pText;
977
978                 actualLength++;
979                 length--;
980                 pText++;
981
982                 if (mch != *pText && (*pText == TEXT_LINE_FEED || *pText == TEXT_CARRIAGE_RETURN))
983                 {
984                         actualLength++;
985                         length--;
986                 }
987
988                 return TEXT_RETBY_LINEFEED;
989         }
990         else
991         {
992                 while (length && (*pText != 0))
993                 {
994                         actualLength++;
995                         length--;
996                         pText++;
997
998                         if (*pText == (wchar_t)L' ' || *pText == TEXT_OBJ_CHARACTER)
999                         {
1000                                 return TEXT_RETBY_NORMAL;
1001                         }
1002                         else if (*pText == TEXT_LINE_FEED || *pText == TEXT_CARRIAGE_RETURN || *pText == TEXT_PARAGRAPH_SEPARATOR)
1003                         {
1004                                 wchar_t mch = *pText;
1005
1006                                 actualLength++;
1007                                 length--;
1008                                 pText++;
1009
1010                                 if (mch != *pText && (*pText == TEXT_LINE_FEED || *pText == TEXT_CARRIAGE_RETURN))
1011                                 {
1012                                         actualLength++;
1013                                         length--;
1014                                 }
1015
1016                                 return TEXT_RETBY_LINEFEED;
1017                         }
1018                 }
1019         }
1020
1021         if (length == 0)
1022         {
1023                 return TEXT_RETBY_LIMITLENGTH;
1024         }
1025
1026         return TEXT_RETBY_NORMAL;
1027 }
1028
1029 int
1030 TextSimple::GetWordWrapLengthEx(const wchar_t* pText, int textLength, int& actualLength) const
1031 {
1032         for (int i = 0; i < textLength; i++)
1033         {
1034                 pText++;
1035         }
1036
1037         int length = textLength;
1038         actualLength = textLength;
1039
1040         const wchar_t* pLastCharacter = pText - 1;
1041         if (*pLastCharacter == TEXT_LINE_FEED || *pLastCharacter == TEXT_CARRIAGE_RETURN)
1042         {
1043                 return TEXT_RETBY_LINEFEED;
1044         }
1045         else if (*pLastCharacter == (wchar_t)L' ' || *pLastCharacter == TEXT_OBJ_CHARACTER)
1046         {
1047                 return TEXT_RETBY_NORMAL;
1048         }
1049
1050         if (*pText == TEXT_OBJ_CHARACTER)
1051         {
1052                 return TEXT_RETBY_NORMAL;
1053         }
1054         else if (*pText == (wchar_t)L' ')
1055         {
1056                 actualLength--;
1057                 length--;
1058                 pText--;
1059         }
1060         else if (*pText == TEXT_LINE_FEED || *pText == TEXT_CARRIAGE_RETURN)
1061         {
1062                 wchar_t mch = *pText;
1063                 pText--;
1064
1065                 if (mch != *pText && (*pText == TEXT_LINE_FEED || *pText == TEXT_CARRIAGE_RETURN))
1066                 {
1067                         actualLength++;
1068                         length++;
1069                         pText++;
1070                 }
1071
1072                 return TEXT_RETBY_LINEFEED;
1073         }
1074         else if (IsChinese(pText))
1075         {
1076                 return TEXT_RETBY_NORMAL;
1077         }
1078
1079         while ((length >= 0) && (*pText != 0))
1080         {
1081                 if (*pText == (wchar_t)L' ' || *pText == TEXT_OBJ_CHARACTER)
1082                 {
1083                         actualLength++;
1084                         length++;
1085                         pText++;
1086
1087                         return TEXT_RETBY_NORMAL;
1088                 }
1089                 else if (*pText == TEXT_LINE_FEED || *pText == TEXT_CARRIAGE_RETURN)
1090                 {
1091                         wchar_t mch = *pText;
1092
1093                         actualLength++;
1094                         length++;
1095                         pText++;
1096
1097                         if (mch != *pText && (*pText == TEXT_LINE_FEED || *pText == TEXT_CARRIAGE_RETURN))
1098                         {
1099                                 actualLength++;
1100                                 length++;
1101                                 pText++;
1102                         }
1103
1104                         return TEXT_RETBY_LINEFEED;
1105                 }
1106
1107                 actualLength--;
1108                 length--;
1109                 pText--;
1110         }
1111
1112         if (actualLength < 0)
1113         {
1114                 actualLength = 0;
1115         }
1116
1117         if (actualLength == 0)
1118         {
1119                 return TEXT_RETBY_LIMITLENGTH;
1120         }
1121
1122         return TEXT_RETBY_NORMAL;
1123 }
1124
1125 Font*
1126 TextSimple::GetCurrentFont(void) const
1127 {
1128         return _pFont;
1129 }
1130
1131 Color
1132 TextSimple::GetCurrentForegroundColor(void) const
1133 {
1134         const TextSimple* pSimpleTextElement = null;
1135         pSimpleTextElement = this;
1136
1137         if (_isAlternateLookEnabled)
1138         {
1139                 return pSimpleTextElement->GetAlternativeForegroundColor();
1140         }
1141         else
1142         {
1143                 return _foregroundColor;
1144         }
1145 }
1146
1147 void
1148 TextSimple::SetBackGroundDrawingModeEnabled(bool enable)
1149 {
1150         _isBackgroundDrawingModeEnabled = enable;
1151 }
1152
1153 bool
1154 TextSimple::IsBackGroundDrawingModeEnable(void) const
1155 {
1156         return _isBackgroundDrawingModeEnabled;
1157 }
1158
1159 int
1160 TextSimple::ConvertEnterToSpace(wchar_t* pDstText, const wchar_t* pSrcText, int textLength)
1161 {
1162         int length = 0;
1163         int i = 0;
1164
1165         for (i = 0; i < textLength; )
1166         {
1167                 if (*pSrcText == TEXT_LINE_FEED)
1168                 {
1169                         *pDstText = (wchar_t)L' ';
1170                         length++;
1171                         pDstText++;
1172                         pSrcText++;
1173                         i++;
1174                 }
1175                 else if (*pSrcText == TEXT_CARRIAGE_RETURN)
1176                 {
1177                         if (*(pSrcText + 1) == TEXT_LINE_FEED)
1178                         {
1179                                 *pDstText = (wchar_t)L' ';
1180                                 length++;
1181                                 pDstText++;
1182                                 pSrcText += 2;
1183                                 i += 2;
1184                         }
1185                         else
1186                         {
1187                                 *pDstText = (wchar_t)L' ';
1188                                 length++;
1189                                 pDstText++;
1190                                 pSrcText++;
1191                                 i++;
1192                         }
1193                 }
1194                 else
1195                 {
1196                         *pDstText = *pSrcText;
1197                         length++;
1198
1199                         pDstText++;
1200                         pSrcText++;
1201                         i++;
1202                 }
1203         }
1204
1205         return length;
1206 }
1207
1208 void
1209 TextSimple::SetUserWrap(TextObjectWrapType userWrap)
1210 {
1211         _userWrap = userWrap;
1212 }
1213
1214 Color
1215 TextSimple::GetCurrentBackgroundColor(void) const
1216 {
1217         return _backgroundColor;
1218 }
1219
1220 Color
1221 TextSimple::GetCurrentOutlineColor(void) const
1222 {
1223         return _outlineColor;
1224 }
1225
1226 int
1227 TextSimple::GetWordLength(int textIndex, int& wordLength) const
1228 {
1229         int length = 0;
1230         const wchar_t* pText = &_pText[textIndex];
1231
1232         length = GetTextOffset() + _length - textIndex;
1233         if (length == 0)
1234         {
1235                 return WORD_ERROR;
1236         }
1237
1238         if (*pText == (wchar_t)L' ')
1239         {
1240                 wordLength = 1;
1241                 return WORD_SPACE;
1242         }
1243         else if (*pText == TEXT_LINE_FEED || *pText == TEXT_CARRIAGE_RETURN
1244                          || *pText == TEXT_PARAGRAPH_SEPARATOR)
1245         {
1246                 if (length == 1)
1247                 {
1248                         wordLength = 1;
1249                         return WORD_ENTER;
1250                 }
1251
1252                 wchar_t mch = *pText;
1253                 pText++;
1254
1255                 if (mch != *pText && (*pText == TEXT_LINE_FEED || *pText == TEXT_CARRIAGE_RETURN))
1256                 {
1257                         wordLength = 2;
1258                         return WORD_ENTER;
1259                 }
1260
1261                 wordLength = 1;
1262                 return WORD_ENTER;
1263         }
1264         else
1265         {
1266                 wordLength = 1;
1267                 length--;
1268                 pText++;
1269
1270                 while (length && (*pText != 0))
1271                 {
1272                         if (*pText == (wchar_t)L' ')
1273                         {
1274                                 return WORD_WORD;
1275                         }
1276                         else if (*pText == TEXT_LINE_FEED || *pText == TEXT_CARRIAGE_RETURN
1277                                          || *pText == TEXT_PARAGRAPH_SEPARATOR)
1278                         {
1279                                 return WORD_WORD;
1280                         }
1281
1282                         length--;
1283                         pText++;
1284                         wordLength++;
1285                 }
1286
1287                 return WORD_WORD;
1288         }
1289
1290         return WORD_ERROR;
1291 }
1292
1293 result
1294 TextSimple::SetBitmap(const Bitmap& bitmap)
1295 {
1296         result r = E_SUCCESS;
1297
1298         Bitmap* pBitmap = new (std::nothrow) Bitmap();
1299         SysTryReturn(NID_GRP
1300                 , pBitmap
1301                 , E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
1302
1303         r = pBitmap->Construct(bitmap, Rectangle(0, 0, bitmap.GetWidth(), bitmap.GetHeight()));
1304         if (r != E_SUCCESS)
1305         {
1306                 delete pBitmap;
1307                 SysLog(NID_GRP, "[%s] Propagating.", GetErrorMessage(r));
1308
1309                 return r;
1310         }
1311
1312         if (__pBitmap)
1313         {
1314                 delete __pBitmap;
1315                 __pBitmap = null;
1316         }
1317
1318         __pBitmap = pBitmap;
1319
1320         return E_SUCCESS;
1321 }
1322
1323 const Bitmap*
1324 TextSimple::GetBitmap(void) const
1325 {
1326         return __pBitmap;
1327 }
1328
1329 int
1330 TextSimple::GetBaseline(void) const
1331 {
1332         Font* pCurrentFont = GetCurrentFont();
1333         SysTryReturn(NID_GRP
1334                 , pCurrentFont
1335                 , E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] This instance is not line wrapped yet.");
1336
1337         _Font* pFont = _Font::GetInstance(*_FontImpl::GetInstance(*pCurrentFont));
1338         SysTryReturn(NID_GRP
1339                         , pFont
1340                         , E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Fail to get native font instance.");
1341
1342         return (-1) * pFont->GetDescender();
1343 }
1344
1345 }}} // Tizen::Graphics::_Text