Improve the underline markup
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / rendering / styles / underline-helper-functions.cpp
1 /*
2  * Copyright (c) 2022 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali-toolkit/internal/text/rendering/styles/underline-helper-functions.h>
20
21 namespace Dali
22 {
23 namespace Toolkit
24 {
25 namespace Text
26 {
27 bool IsGlyphUnderlined(GlyphIndex                                 index,
28                        const Vector<UnderlinedGlyphRun>&          underlineRuns,
29                        Vector<UnderlinedGlyphRun>::ConstIterator& currentUnderlinedGlyphRunIt)
30 {
31   for(Vector<UnderlinedGlyphRun>::ConstIterator it    = underlineRuns.Begin(),
32                                                 endIt = underlineRuns.End();
33       it != endIt;
34       ++it)
35   {
36     const UnderlinedGlyphRun& run = *it;
37
38     if((run.glyphRun.glyphIndex <= index) && (index < run.glyphRun.glyphIndex + run.glyphRun.numberOfGlyphs))
39     {
40       currentUnderlinedGlyphRunIt = it;
41       return true;
42     }
43   }
44
45   return false;
46 }
47
48 UnderlineStyleProperties GetCurrentUnderlineProperties(GlyphIndex                                 index,
49                                                        const bool&                                isGlyphUnderlined,
50                                                        const Vector<UnderlinedGlyphRun>&          underlineRuns,
51                                                        Vector<UnderlinedGlyphRun>::ConstIterator& currentUnderlinedGlyphRunIt,
52                                                        const UnderlineStyleProperties&            commonUnderlineProperties)
53 {
54   UnderlineStyleProperties currentUnderlineStyleProperties = commonUnderlineProperties;
55
56   if(isGlyphUnderlined && (currentUnderlinedGlyphRunIt != underlineRuns.End()))
57   {
58     // Retrieve the latest run to handle the nested case.
59     for(Vector<UnderlinedGlyphRun>::ConstIterator it    = currentUnderlinedGlyphRunIt + 1,
60                                                   endIt = underlineRuns.End();
61         it != endIt;
62         ++it)
63     {
64       const UnderlinedGlyphRun& run = *it;
65
66       if((run.glyphRun.glyphIndex <= index) && (index < (run.glyphRun.glyphIndex + run.glyphRun.numberOfGlyphs)))
67       {
68         currentUnderlinedGlyphRunIt = it;
69       }
70     }
71
72     currentUnderlineStyleProperties.OverrideByDefinedProperties(currentUnderlinedGlyphRunIt->properties);
73   }
74
75   return currentUnderlineStyleProperties;
76 }
77
78 float FetchUnderlinePositionFromFontMetrics(const FontMetrics& fontMetrics)
79 {
80   //Helper method to fetch the underline metrics for the specified font glyph
81   const float descender         = ceil(fabsf(fontMetrics.descender));
82   float       underlinePosition = ceil(fabsf(fontMetrics.underlinePosition));
83
84   // Clamp the underline position at the font descender and check for ( as EFL describes it ) a broken font
85   if(underlinePosition > descender)
86   {
87     underlinePosition = descender;
88   }
89
90   if(fabsf(underlinePosition) < Math::MACHINE_EPSILON_1000)
91   {
92     // Move offset down by one ( EFL behavior )
93     underlinePosition = 1.0f;
94   }
95
96   return underlinePosition;
97 }
98
99 void CalcualteUnderlineHeight(const FontMetrics& fontMetrics, float& currentUnderlineHeight, float& maxUnderlineHeight)
100 {
101   //Helper method to fetch the underline metrics for the specified font glyph
102   //Height of underline represents the thickness of line.
103   if(fabsf(currentUnderlineHeight) < Math::MACHINE_EPSILON_1000)
104   {
105     currentUnderlineHeight = fontMetrics.underlineThickness;
106
107     // Ensure underline will be at least a pixel high
108     if(currentUnderlineHeight < 1.0f)
109     {
110       currentUnderlineHeight = 1.0f;
111     }
112     else
113     {
114       currentUnderlineHeight = ceil(currentUnderlineHeight);
115     }
116   }
117
118   // The underline height should be the max underline height of all glyphs of the line.
119   if(currentUnderlineHeight > maxUnderlineHeight)
120   {
121     maxUnderlineHeight = currentUnderlineHeight;
122   }
123 }
124
125 } // namespace Text
126
127 } // namespace Toolkit
128
129 } // namespace Dali